text: // *****************************************************************************
  // *****************************************************************************
  // Copyright 2012 - 2017, Cadence Design Systems
  //
  // This  file  is  part  of  the  Cadence  LEF/DEF  Open   Source
  // Distribution,  Product Version 5.8.
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  //    you may not use this file except in compliance with the License.
  //    You may obtain a copy of the License at
  //
  //        http://www.apache.org/licenses/LICENSE-2.0
  //
  //    Unless required by applicable law or agreed to in writing, software
  //    distributed under the License is distributed on an "AS IS" BASIS,
  //    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  //    implied. See the License for the specific language governing
  //    permissions and limitations under the License.
  //
  // For updates, support, or to become part of the LEF/DEF Community,
  // check www.openeda.org for details.
  // *****************************************************************************
  // *****************************************************************************
  
  // This file contains code for implementing the lefwriter 5.3
  // It has all the functions user can call in their callbacks or
  // just their writer to write out the correct lef syntax.
  //
  // Author: Wanda da Rosa
  // Date:   Summer, 1998
  //
  // Revisions:
  
  #include "lefwWriter.hpp"
  
  #include <stdlib.h>
  #include <string.h>
  #include <time.h>
  
  #include "crypt.hpp"
  
  BEGIN_LEFDEF_PARSER_NAMESPACE
  
  // States of the writer.
  #define LEFW_UNINIT                0
  #define LEFW_INIT                  1
  #define LEFW_ARRAY_START           2
  #define LEFW_BEGINEXT_START        3
  #define LEFW_CORRECTTABLE_START    4
  #define LEFW_IRDROP_START          5
  #define LEFW_LAYER_START           6
  #define LEFW_LAYERROUTING_START    7
  #define LEFW_LAYERROUTING_SP_START 8
  #define LEFW_MACRO_START           9
  #define LEFW_NOISETABLE_START      10
  #define LEFW_NONDEFAULTRULE_START  11
  #define LEFW_PROPERTYDEF_START     12
  #define LEFW_SPACING_START         13
  #define LEFW_UNITS_START           14
  #define LEFW_VIA_START             15
  #define LEFW_VIARULE_START         16
  #define LEFW_VIARULEGEN_START      17
  
  #define LEFW_ANTENNASIZE                18
  #define LEFW_ARRAY                      19
  #define LEFW_BEGINEXT                   20
  #define LEFW_BUSBITCHARS                21
  #define LEFW_CASESENSITIVE              22
  #define LEFW_CORRECTTABLE               23
  #define LEFW_DIELECTRIC                 24
  #define LEFW_DIVIDERCHAR                25
  #define LEFW_EDGERATE                   26
  #define LEFW_IRDROP                     27
  #define LEFW_LAYER                      28
  #define LEFW_LAYERACCURRENT             29
  #define LEFW_LAYERDCCURRENT             30
  #define LEFW_LAYERROUTING               31
  #define LEFW_LAYERROUTINGWIDTH          32
  #define LEFW_MACRO                      33
  #define LEFW_MACRO_CAPACITANCE          34
  #define LEFW_MACRO_INPUTNOISEMARGIN     35
  #define LEFW_MACRO_FALLCURRENTSOURCE    36
  #define LEFW_MACRO_FALLSATCUR           37
  #define LEFW_MACRO_FALLTHRESH           38
  #define LEFW_MACRO_FALLVOLTAGETHRESHOLD 39
  #define LEFW_MACRO_IV_TABLES            40
  #define LEFW_MACRO_LEAKAGE              41
  #define LEFW_MACRO_LEQ                  42
  #define LEFW_MACRO_OUTPUTNOISEMARGIN    43
  #define LEFW_MACRO_OUTPUTRESISTANCE     44
  #define LEFW_MACRO_PINFOREIGN           45
  #define LEFW_MACRO_PINLEQ               46
  #define LEFW_MACRO_POWER                47
  #define LEFW_MACRO_PULLDOWNRES          48
  #define LEFW_MACRO_RESISTANCE           49
  #define LEFW_MACRO_RISESATCUR           50
  #define LEFW_MACRO_RISETHRESH           51
  #define LEFW_MACRO_RISEVOLTAGETHRESHOLD 52
  #define LEFW_MACRO_SOURCE               53
  #define LEFW_MACRO_TIEOFFR              54
  #define LEFW_MACRO_TIMING               55
  #define LEFW_MACRO_VHI                  56
  #define LEFW_MACRO_VLO                  57
  #define LEFW_MINFEATURE                 58
  #define LEFW_NONDEFAULTRULE             59
  #define LEFW_NONDEFAULTRULELAYER        60
  #define LEFW_NOISEMARGIN                61
  #define LEFW_NOISETABLE                 62
  #define LEFW_NOWIREEXTATPIN             63
  #define LEFW_PROPERTYDEF                64
  #define LEFW_SCALEFACTOR                65
  #define LEFW_SITE                       66
  #define LEFW_SPACING                    67
  #define LEFW_THRESHOLD1                 68
  #define LEFW_THRESHOLD2                 69
  #define LEFW_UNITS                      70
  #define LEFW_VERSION                    71
  #define LEFW_VIA                        72
  #define LEFW_VIAFOREIGN                 73
  #define LEFW_VIARULE                    74
  #define LEFW_VIARULEGENERATE            75
  #define LEFW_VIARULEGEN                 76
  #define LEFW_VIATOPOFSTACKONLY          77
  #define LEFW_VIAVIARULE                 78
  
  #define LEFW_END                           79
  #define LEFW_ARRAY_END                     80
  #define LEFW_BEGINEXT_END                  81
  #define LEFW_CORRECTTABLE_END              82
  #define LEFW_IRDROP_END                    83
  #define LEFW_LAYER_END                     84
  #define LEFW_LAYERROUTING_END              85
  #define LEFW_LAYERROUTING_SPACINGTABLE_END 86
  #define LEFW_MACRO_END                     87
  #define LEFW_NOISETABLE_END                88
  #define LEFW_NONDEFAULTRULE_END            89
  #define LEFW_PROPERTYDEF_END               90
  #define LEFW_SITE_END                      91
  #define LEFW_SPACING_END                   92
  #define LEFW_VIA_END                       93
  #define LEFW_VIARULE_END                   94
  #define LEFW_VIARULEGEN_END                95
  #define LEFW_UNITS_END                     96
  
  // 5.4
  // ANTENNA for LAYER
  #define LEFW_ANTENNAINPUTGATEAREA           97
  #define LEFW_ANTENNAINOUTDIFFAREA           98
  #define LEFW_ANTENNAOUTPUTDIFFAREA          99
  #define LEFW_ANTENNAMODEL                   100
  #define LEFW_ANTENNAAREARATIO               101
  #define LEFW_ANTENNADIFFAREARATIO           102
  #define LEFW_ANTENNADIFFAREARATIOPWL        103
  #define LEFW_ANTENNACUMAREARATIO            104
  #define LEFW_ANTENNACUMDIFFAREARATIO        105
  #define LEFW_ANTENNACUMDIFFAREARATIOPWL     106
  #define LEFW_ANTENNAAREAFACTOR              107
  #define LEFW_ANTENNASIDEAREARATIO           108
  #define LEFW_ANTENNADIFFSIDEAREARATIO       109
  #define LEFW_ANTENNADIFFSIDEAREARATIOPWL    110
  #define LEFW_ANTENNACUMSIDEAREARATIO        111
  #define LEFW_ANTENNACUMDIFFSIDEAREARATIO    112
  #define LEFW_ANTENNACUMDIFFSIDEAREARATIOPWL 113
  #define LEFW_ANTENNASIDEAREAFACTOR          114
  // ANTENNA for MACRO PIN
  #define LEFW_ANTENNAPARTIALMETALAREA     115
  #define LEFW_ANTENNAPARTIALMETALSIDEAREA 116
  #define LEFW_ANTENNAGATEAREA             117
  #define LEFW_ANTENNADIFFAREA             118
  #define LEFW_ANTENNAMAXAREACAR           119
  #define LEFW_ANTENNAMAXSIDEAREACAR       120
  #define LEFW_ANTENNAPARTIALCUTAREA       121
  #define LEFW_ANTENNAMAXCUTCAR            122
  #define LEFW_CLEARANCEMEASURE            123
  #define LEFW_DENSITYCHECKWINDOW          124
  #define LEFW_DENSITYCHECKSTEP            125
  #define LEFW_DESIGNRULEWIDTH             126
  #define LEFW_FILLACTIVESPACING           127
  #define LEFW_MANUFACTURINGGRID           128
  #define LEFW_MAXADJACENTSLOTSPACING      129
  #define LEFW_MAXCOAXIALSLOTSPACING       130
  #define LEFW_MAXEDGESLOTSPACING          131
  #define LEFW_MAXIMUMDENSITY              132
  #define LEFW_MINIMUMDENSITY              133
  #define LEFW_ROWABUTSPACING              134
  #define LEFW_ROWMINSPACING               135
  #define LEFW_SLOTWIREWIDTH               136
  #define LEFW_SLOTWIRELENGTH              137
  #define LEFW_SLOTWIDTH                   138
  #define LEFW_SLOTLENGTH                  139
  #define LEFW_SPLITWIREWIDTH              140
  #define LEFW_USEMINSPACING               141
  #define LEFW_FIXEDMASK                   142
  
  #define LEFW_DONE 999
  
  #define MAXSYN 143
  
  // *****************************************************************************
  // Global Variables
  // *****************************************************************************
  typedef void (*LEFI_LOG_FUNCTION)(const char *);
  typedef void (*LEFI_WARNING_LOG_FUNCTION)(const char *);
  
  LEFI_LOG_FUNCTION         lefwErrorLogFunction;
  LEFI_WARNING_LOG_FUNCTION lefwWarningLogFunction;
  
  FILE *        lefwFile = 0;                              // File to write to.
  int           lefwSynArray[MAXSYN];                      // array of syntax
  int           lefwLines                  = 0;            // number of lines written
  int           lefwState                  = LEFW_UNINIT;  // Current state of writer
  int           lefwDidInit                = 0;            // required section
  int           lefwDidLayer               = 0;            // required section
  int           lefwDidVia                 = 0;            // required section
  int           lefwDidViaRule             = 0;            // required section
  int           lefwDidViaSite             = 0;            // required section
  int           lefwDidViaMacro            = 0;            // required section
  int           lefwCounter                = 0;            // number of nets, components in section
  int           lefwLineItemCounter        = 0;            // number of items on current line
  int           lefwHasArrayReq            = 0;            // array required data
  int           lefwIsArrayFloorp          = 0;            // array floorplan flag
  int           lefwIsArrayDef             = 0;            // array default cap flag
  int           lefwIsCorrectTable         = 0;            // correctiontable flag
  int           lefwIsCut                  = 0;            // cut layer
  int           lefwIsEdgerate             = 0;            // edgerate within noisetable
  int           lefwIsFloorp               = 0;            // floorplan within array
  int           lefwIsImplant              = 0;            // implant layer
  int           lefwIsMacroDensity         = 0;            // macro density flag
  int           lefwIsMacroObs             = 0;            // macro obs flag
  int           lefwIsMacroObsLayer        = 0;            // macro obs layer within macro obs
  int           lefwIsMacroPin             = 0;            // macro pin flag
  int           lefwIsMacroPinPortLayer    = 0;            // macro pin port layer within macro pin port
  int           lefwIsMacroPinPort         = 0;            // macro pin port within macro pin
  int           lefwIsMacroTiming          = 0;            // macro timing flag
  int           lefwIsMacroTimingModel     = 0;            // macro timing model flag
  int           lefwIsMaxviastack          = 0;            // maximum stacked-via
  int           lefwIsNoiseTable           = 0;            // noisetable flag
  int           lefwIsNonDefaultRule       = 0;            // nondefaultrule flag
  int           lefwIsOutResist            = 0;            // outputResistance within edgerate
  int           lefwIsRouting              = 0;            // routing
  int           lefwIsRoutingMinCut        = 0;            // routing Minimumcut
  int           lefwIsRoutingMinCutDist    = 0;            // routing Minimumcut distance
  int           lefwIsRoutingMinCutLen     = 0;            // routing Minimumcut length within
  int           lefwIsRoutingReqData       = 0;            // layer routing required data are provided
  int           lefwNumViaRuleLayers       = 0;            // number of via rule in a via rule
  int           lefwOldState               = 0;            // the previous state
  int           lefwTableLen               = 0;            // width or cutarea for the tableEntries
  int           lefwHasInit                = 0;            // for lefwInit has called
  int           lefwHasInitCbk             = 0;            // for lefwInitCbk has called
  static int    lefwWriteEncrypt           = 0;            // for writing out encrypted file, default is 0
  static int    prtSemiColon               = 0;            // sometimes ; is not printed yet
  static int    prtNewLine                 = 0;            // sometimes need to print a new line
  static int    lefwHasLayerRoutingRange   = 0;            // mark if layer routing has range
  static int    lefwHasLayerRoutingSpacing = 0;            // layer routing is lengththreshold
  static int    lefwHasLayerRoutingEol     = 0;            // mark if layer routing is endofline
  static int    lefwIsLayerCutSpacing      = 0;            // mark if layer cut spacing
  static int    lefwAMaxAreaCar            = 0;            // only allow to define once per pin
  static int    lefwAMaxSideAreaCar        = 0;            // only allow to define once per pin
  static int    lefwAMaxCutCar             = 0;            // only allow to define once per pin
  static int    lefwSpacingVal             = 0;            // either this or lefwWidthVal
  static int    lefwWidthVal               = 0;            // is allowed
  static double versionNum                 = 5.7;          // default to 5.7
  static int    lefwAntenna54              = 0;            // to keep track 5.4 antenna is used
  static int    lefwAntenna53              = 0;            // to keep track 5.3 antenna is used
  static int    lefwObsoleteNum            = -1;           // keep track the obsolote syntax for error
  static int    lefw54Num                  = -1;           // keep track the 5.4 syntax for error
  static int    lefwViaHasVal              = 0;            // keep track only ViaRule or Resistance in a via
  
  char lefwStateStr[MAXSYN][80] = {
      "UNITS",                                          //  0
      "INIT",                                           //  1
      "ARRAY",                                          //  2
      "BEGINEXT",                                       //  3
      "CORRECTTABLE",                                   //  4
      "IRDROP",                                         //  5
      "LAYER",                                          //  6
      "LAYERROUTING",                                   //  7
      "LAYERROUTINGSPACINGTABLE",                       //  8
      "MACRO",                                          //  9
      "NOISETABLE",                                     // 10
      "NONDEFAULTRULE",                                 // 11
      "PROPERTYDEFINITION",                             // 12
      "SPACING",                                        // 13
      "UNITS",                                          // 14
      "VIA",                                            // 15
      "VIARULE",                                        // 16
      "VIARULEGEN",                                     // 17
      "ANTENNASIZE",                                    // 18
      "ARRAY",                                          // 19
      "BEGINEXT",                                       // 20
      "BUSBITCHARS",                                    // 21
      "CASESENSITIVE",                                  // 22
      "CORRECTABLE",                                    // 23
      "DIELECTRIC",                                     // 24
      "DIVIDERCHAR",                                    // 25
      "EDGERATE",                                       // 26
      "IRDROP",                                         // 27
      "LAYER",                                          // 28
      "LAYERACCURRENT",                                 // 29
      "LAYERDCCURRENT",                                 // 30
      "LAYERROUTING",                                   // 31
      "LAYERROUTINGWIDTH",                              // 32
      "MACRO",                                          // 33
      "MACRO_CAPACITANCE",                              // 34
      "MACRO_INPUTNOISEMARGIN",                         // 35
      "MACRO_FALLCURRENTSOURCE",                        // 36
      "MACRO_FALLSATCUR",                               // 37
      "MACRO_FALLTHRESH",                               // 38
      "MACRO_FALLVOLTAGETHRESHOLD",                     // 39
      "MACRO_IV_TABLES",                                // 40
      "MACRO_LEAKAGE",                                  // 41
      "MACRO_LEQ",                                      // 42
      "MACRO_OUTPUTNOISEMARGIN",                        // 43
      "MACRO_OUTPUTRESISTANCE",                         // 44
      "MACRO_PINFOREIGN",                               // 45
      "MACRO_PINLEQ",                                   // 46
      "MACRO_POWER",                                    // 47
      "MACRO_PULLDOWNRES",                              // 48
      "MACRO_RESISTANCE",                               // 49
      "MACRO_RISESATCUR",                               // 50
      "MACRO_RISETHRESH",                               // 51
      "MACRO_RISEVOLTAGETHRESHOLD",                     // 52
      "MACRO_SOURCE",                                   // 53
      "MACRO_TIEOFFR",                                  // 54
      "MACRO_TIMING",                                   // 55
      "MACRO_VHI",                                      // 56
      "MACRO_VLO",                                      // 57
      "MINFEATURE",                                     // 58
      "NONDEFAULTRULE",                                 // 59
      "NONDEFAULTRULELAYERRESIST_CAPACITANCE_EDGECAP",  // 60
      "NOISEMARGIN",                                    // 61
      "NOISETABLE",                                     // 62
      "NOWIREEXTSIONATPIN",                             // 63
      "PROPERTYDEFINITION",                             // 64
      "EDGERATESCALEFACTOR",                            // 65
      "SITE",                                           // 66
      "SPACING",                                        // 67
      "EDGERATETHRESHOLD1",                             // 68
      "EDGERATETHRESHOLD2",                             // 69
      "UNTIS",                                          // 70
      "VERSION",                                        // 71
      "VIA",                                            // 72
      "VIAFOREIGN",                                     // 73
      "VIARULE",                                        // 74
      "VIARULEDIRECTION_OVERHANG_METALOVERHANG",        // 75
      "VIARULEGEN",                                     // 76
      "VIATOPOFSTACKONLY",                              // 77
      "VIAVIARULE",                                     // 78
      "END",                                            // 79
      "ARRAY",                                          // 80
      "BEGINEXT",                                       // 81
      "CORRECTABLE",                                    // 82
      "IRDROP",                                         // 83
      "LAYER",                                          // 84
      "LAYERROUTING",                                   // 85
      "LAYERROUTINGSPACINGTABLE",                       // 86
      "MACRO",                                          // 87
      "NOISETABLE",                                     // 88
      "NONDEFAULTRULE",                                 // 89
      "PROERTYDEFINITION",                              // 90
      "SITE",                                           // 91
      "SPACING",                                        // 92
      "VIA",                                            // 93
      "VIARULE",                                        // 94
      "VIARULEGEN",                                     // 95
      "UNITS",                                          // 96
      "ANTENNAINPUTGATEAREA",                           // 97
      "ANTENNAINOUTDIFFAREA",                           // 98
      "ANTENNAOUTPUTDIFFAREA",                          // 99
      "ANTENNAMODEL",                                   // 100
      "ANTENNAAREARATIO",                               // 101
      "ANTENNADIFFAREARATIO",                           // 102
      "ANTENNADIFFAREARATIO PWL",                       // 103
      "ANTENNACUMAREARATIO",                            // 104
      "ANTENNACUMDIFFAREARATIO",                        // 105
      "ANTENNACUMDIFFAREARATIO PWL",                    // 106
      "ANTENNAAREAFACTOR",                              // 107
      "ANTENNASIDEAREARATIO",                           // 108
      "ANTENNADIFFSIDEAREARATIO",                       // 109
      "ANTENNADIFFSIDEAREARATIO PWL",                   // 110
      "ANTENNACUMSIDEAREARATIO",                        // 111
      "ANTENNACUMDIFFSIDEAREARATIO",                    // 112
      "ANTENNACUMDIFFSIDEAREARATIO PWL",                // 113
      "ANTENNASIDEAREAFACTOR",                          // 114
      "ANTENNAPARTIALMETALAREA",                        // 115
      "ANTENNAPARTIALMETALSIDEAREA",                    // 116
      "ANTENNAGATEAREA",                                // 117
      "ANTENNADIFFAREA",                                // 118
      "ANTENNAMAXAREACAR",                              // 119
      "ANTENNAMAXSIDEAREACAR",                          // 120
      "ANTENNAPARTIALCUTAREA",                          // 121
      "ANTENNAMAXCUTCAR",                               // 122
      "CLEARANCEMEASURE",                               // 123
      "DENSITYCHECKWINDOW",                             // 124
      "DENSITYCHECKSTEP",                               // 125
      "DESIGNRULEWIDTH",                                // 126
      "FILLACTIVESPACING",                              // 127
      "MANUFACTURINGGRID",                              // 128
      "MAXADJACENTSLOTSPACING",                         // 129
      "MAXCOAXIALSLOTSPACING",                          // 130
      "MAXEDGESLOTSPACING",                             // 131
      "MAXIMUMDENSITY",                                 // 132
      "MINIMUMDENSITY",                                 // 133
      "ROWABUTSPACING",                                 // 134
      "ROWMINSPACING",                                  // 135
      "SLOTWIREWIDTH",                                  // 136
      "SLOTWIRELENGTH",                                 // 137
      "SLOTWIDTH",                                      // 138
      "SLOTLENGTH",                                     // 139
      "SPLITWIREWIDTH",                                 // 140
      "USEMINSPACING PIN"                               // 141
  };
  
  // internal function
  char *lefwAddr(const char *x) { return (char *)x; }
  
  // internal function
  char *lefwOrient(int num) {
    switch (num) {
      case 0: return lefwAddr("N");
      case 1: return lefwAddr("W");
      case 2: return lefwAddr("S");
      case 3: return lefwAddr("E");
      case 4: return lefwAddr("FN");
      case 5: return lefwAddr("FW");
      case 6: return lefwAddr("FS");
      case 7: return lefwAddr("FE");
    };
    return lefwAddr("BOGUS");
  }
  
  // internal function
  bool lefwValidateMaskNumber(int num) {
    int digit = 0;
    int index = 0;
  
    if (num < 0) {
      return false;
    }
  
    while (num > 0) {
      digit = num % 10;
  
      if (digit > 3) {
        return false;
      }
  
      index++;
      num = num / 10;
    }
  
    if (index > 3) {
      return false;
    }
  
    return true;
  }
  
  // this function is required to be called first to initialize the array
  // Either this function or lefwInitCbk can be called, cannot be both
  int lefwInit(FILE *f) {
    int i;
  
    // Check if the user is valid
    /* don't need anymore
    if (!lefiValidUser())
        exit(77);
    */
  
    // if (lefwFile) return LEFW_BAD_ORDER;
    lefwFile = f;
  
    if (lefwHasInitCbk == 1) {  // lefwInitCbk has already called, issue an error
      fprintf(lefwFile, "ERROR (LEFWRIT-4000): lefwInitCbk has already called, cannot call lefwInit again.\n");
      fprintf(lefwFile, "Writer Exit.\n");
      exit(LEFW_BAD_ORDER);
    }
    lefwState   = LEFW_UNINIT;  // Current state of writer
    lefwDidInit = 0;            // required section
  
    for (i = 0; i < MAXSYN; i++) lefwSynArray[i] = 0;
  
    lefwDidInit = 1;
    lefwState   = LEFW_INIT;
    lefwHasInit = 1;
    return LEFW_OK;
  }
  
  // this function is required to be called first to initialize the array
  // Either this function or lefwInit can be called, cannot be both
  int lefwInitCbk(FILE *f) {
    int i;
  
    // if (lefwFile) return LEFW_BAD_ORDER;
    lefwFile = f;
  
    if (lefwHasInit == 1) {  // lefwInit has already called, issue an error
      if (lefwWriteEncrypt) {
        encPrint(lefwFile, (char *)"ERROR (LEFWRIT-4001): lefwInit has already called, cannot call lefwInitCbk again.\n");
        encPrint(lefwFile, (char *)"Writer Exit.\n");
      } else {
        fprintf(lefwFile, "ERROR (LEFWRIT-4002): lefwInit has already called, cannot call lefwInitCbk again.\n");
        fprintf(lefwFile, "Writer Exit.\n");
      }
      exit(LEFW_BAD_ORDER);
    }
    lefwState   = LEFW_UNINIT;  // Current state of writer
    lefwDidInit = 0;            // required section
  
    for (i = 0; i < MAXSYN; i++) lefwSynArray[i] = 0;
  
    lefwDidInit    = 1;
    lefwState      = LEFW_INIT;
    lefwHasInitCbk = 1;
    return LEFW_OK;
  }
  
  // This function sets the global variable lefwEncrypt to 1, which will
  // write out an output encrypted file, make sure to call lefwCloseEncrypt
  // before closing the output file
  int lefwEncrypt() {
    if (!lefwFile || (lefwFile == stdout)) {
      // No output filename is given
      fprintf(stderr, "ERROR (LEFWRITE-4006): Need an output file if writing in encrypted format.\n");
      return LEFW_BAD_ORDER;
    }
  
    // Set the flag in crypt.cpp
    encWritingEncrypted();
  
    lefwWriteEncrypt = 1;
    return LEFW_OK;
  }
  
  // This function needs to be called if lefwEncrypt is called
  // It will clear the encrypted buffer
  int lefwCloseEncrypt() {
    if (lefwWriteEncrypt)
      encClearBuf(lefwFile);
    return LEFW_OK;
  }
  
  int lefwNewLine() {
    if (!lefwFile)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"\n");
    else
      fprintf(lefwFile, "\n");
    return LEFW_OK;
  }
  
  int lefwVersion(int vers1, int vers2) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (lefwSynArray[LEFW_VERSION])
      return LEFW_ALREADY_DEFINED;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"VERSION %d.%d ;\n", vers1, vers2);
    else
      fprintf(lefwFile, "VERSION %d.%d ;\n", vers1, vers2);
    if (vers2 >= 10)
      versionNum = vers1 + (vers2 / 100.0);
    else
      versionNum = vers1 + (vers2 / 10.0);
    lefwSynArray[LEFW_VERSION] = 1;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwCaseSensitive(const char *caseSensitive) {
    lefwObsoleteNum = LEFW_CASESENSITIVE;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (versionNum >= 5.6)
      return LEFW_OBSOLETE;
    if (lefwSynArray[LEFW_CASESENSITIVE])
      return LEFW_ALREADY_DEFINED;
    if (strcmp(caseSensitive, "ON") && strcmp(caseSensitive, "OFF"))
      return LEFW_BAD_DATA;  // has to be either ON or OFF
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"NAMESCASESENSITIVE %s ;\n", caseSensitive);
    else
      fprintf(lefwFile, "NAMESCASESENSITIVE %s ;\n", caseSensitive);
    lefwSynArray[LEFW_CASESENSITIVE] = 1;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwNoWireExtensionAtPin(const char *noWireExt) {
    lefwObsoleteNum = LEFW_NOWIREEXTATPIN;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (versionNum >= 5.6)
      return LEFW_OBSOLETE;
    if (lefwSynArray[LEFW_NOWIREEXTATPIN])
      return LEFW_ALREADY_DEFINED;
    if (strcmp(noWireExt, "ON") && strcmp(noWireExt, "OFF"))
      return LEFW_BAD_DATA;  // has to be either ON or OFF
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"NOWIREEXTENSIONATPIN %s ;\n", noWireExt);
    else
      fprintf(lefwFile, "NOWIREEXTENSIONATPIN %s ;\n", noWireExt);
    lefwSynArray[LEFW_NOWIREEXTATPIN] = 1;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwMinfeature(double minFeatureX, double minFeatureY) {
    lefwObsoleteNum = LEFW_MINFEATURE;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwSynArray[LEFW_MINFEATURE])
      return LEFW_ALREADY_DEFINED;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"MINFEATURE %.11g %.11g ;\n", minFeatureX, minFeatureY);
    else
      fprintf(lefwFile, "MINFEATURE %.11g %.11g ;\n", minFeatureX, minFeatureY);
    lefwSynArray[LEFW_MINFEATURE] = 1;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwDielectric(double dielectric) {
    lefwObsoleteNum = LEFW_DIELECTRIC;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwSynArray[LEFW_DIELECTRIC])
      return LEFW_ALREADY_DEFINED;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"DIELECTRIC %.11g ;\n", dielectric);
    else
      fprintf(lefwFile, "DIELECTRIC %.11g ;\n", dielectric);
    lefwSynArray[LEFW_DIELECTRIC] = 1;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwBusBitChars(const char *busBitChars) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (lefwSynArray[LEFW_BUSBITCHARS])
      return LEFW_ALREADY_DEFINED;
    if (busBitChars && busBitChars != 0 && *busBitChars != 0) {
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)"BUSBITCHARS \"%s\" ;\n", busBitChars);
      else
        fprintf(lefwFile, "BUSBITCHARS \"%s\" ;\n", busBitChars);
    }
    lefwLines++;
    lefwSynArray[LEFW_BUSBITCHARS] = 1;
    return LEFW_OK;
  }
  
  int lefwDividerChar(const char *dividerChar) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (lefwSynArray[LEFW_DIVIDERCHAR])
      return LEFW_ALREADY_DEFINED;
    if (dividerChar && dividerChar != 0 && *dividerChar != 0) {
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)"DIVIDERCHAR \"%s\" ;\n", dividerChar);
      else
        fprintf(lefwFile, "DIVIDERCHAR \"%s\" ;\n", dividerChar);
    }
    lefwLines++;
    lefwSynArray[LEFW_DIVIDERCHAR] = 1;
    return LEFW_OK;
  }
  
  int lefwManufacturingGrid(double grid) {
    lefw54Num = LEFW_MANUFACTURINGGRID;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (lefwSynArray[LEFW_MANUFACTURINGGRID])
      return LEFW_ALREADY_DEFINED;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"MANUFACTURINGGRID %.11g ;\n", grid);
    else
      fprintf(lefwFile, "MANUFACTURINGGRID %.11g ;\n", grid);
    lefwLines++;
    lefwSynArray[LEFW_MANUFACTURINGGRID] = 1;
    return LEFW_OK;
  }
  
  int lefwFixedMask() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
  
    if (versionNum < 5.8)
      return LEFW_WRONG_VERSION;
  
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"FIXEDMASK ;\n");
    else
      fprintf(lefwFile, "FIXEDMASK ;\n");
  
    lefwLines++;
    lefwSynArray[LEFW_FIXEDMASK] = 1;
    return LEFW_OK;
  }
  
  int lefwUseMinSpacing(const char *type, const char *onOff) {
    lefwObsoleteNum = LEFW_USEMINSPACING;
    lefw54Num       = LEFW_USEMINSPACING;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    // Can define more than once
    // if (lefwSynArray[LEFW_USEMINSPACING]) return LEFW_ALREADY_DEFINED;
    if (!type || (strcmp(type, "OBS") && strcmp(type, "PIN")))
      return LEFW_BAD_DATA;  // has to be OBS or PIN
    if ((strcmp(type, "PIN") == 0) && (versionNum >= 5.6))
      return LEFW_OBSOLETE;
    if (!onOff || (strcmp(onOff, "ON") && strcmp(onOff, "OFF")))
      return LEFW_BAD_DATA;  // has to be ON or OFF
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"USEMINSPACING %s %s ;\n", type, onOff);
    else
      fprintf(lefwFile, "USEMINSPACING %s %s ;\n", type, onOff);
    lefwLines++;
    // lefwSynArray[LEFW_USEMINSPACING] = 1;
    return LEFW_OK;
  }
  
  int lefwClearanceMeasure(const char *type) {
    lefw54Num = LEFW_CLEARANCEMEASURE;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (lefwSynArray[LEFW_CLEARANCEMEASURE])
      return LEFW_ALREADY_DEFINED;
    if (!type || (strcmp(type, "MAXXY") && strcmp(type, "EUCLIDEAN")))
      return LEFW_BAD_DATA;  // has to be MAXXY or EUCLIDEAN
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"CLEARANCEMEASURE %s ;\n", type);
    else
      fprintf(lefwFile, "CLEARANCEMEASURE %s ;\n", type);
    lefwLines++;
    lefwSynArray[LEFW_CLEARANCEMEASURE] = 1;
    return LEFW_OK;
  }
  
  int lefwStartUnits() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwSynArray[LEFW_UNITS_START])
      return LEFW_ALREADY_DEFINED;
  
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"UNITS\n");
    else
      fprintf(lefwFile, "UNITS\n");
    lefwLines++;
    lefwSynArray[LEFW_UNITS_START] = 1;
    lefwState                      = LEFW_UNITS_START;
    return LEFW_OK;
  }
  
  int lefwUnits(double time,         // optional
                double capacitance,  // optional
                double resistance,   // optional
                double power,        // optional
                double current,      // optional
                double voltage,      // optional
                double database      // optional
  ) {
    int databaseVal;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_UNITS_START && lefwState != LEFW_UNITS)
      return LEFW_BAD_ORDER;
  
    if (time) {
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)"   TIME NANOSECONDS %.11g ;\n", time);
      else
        fprintf(lefwFile, "   TIME NANOSECONDS %.11g ;\n", time);
    }
    if (capacitance) {
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)"   CAPACITANCE PICOFARADS %.11g ;\n", capacitance);
      else
        fprintf(lefwFile, "   CAPACITANCE PICOFARADS %.11g ;\n", capacitance);
    }
    if (resistance) {
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)"   RESISTANCE OHMS %.11g ;\n", resistance);
      else
        fprintf(lefwFile, "   RESISTANCE OHMS %.11g ;\n", resistance);
    }
    if (power) {
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)"   POWER MILLIWATTS %.11g ;\n", power);
      else
        fprintf(lefwFile, "   POWER MILLIWATTS %.11g ;\n", power);
    }
    if (current) {
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)"   CURRENT MILLIAMPS %.11g ;\n", current);
      else
        fprintf(lefwFile, "   CURRENT MILLIAMPS %.11g ;\n", current);
    }
    if (voltage) {
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)"   VOLTAGE VOLTS %.11g ;\n", voltage);
      else
        fprintf(lefwFile, "   VOLTAGE VOLTS %.11g ;\n", voltage);
    }
    if (database) {
      databaseVal = (int)database;
      switch (databaseVal) {
        case 100:
        case 200:
        case 1000:
        case 2000:
        case 10000:
        case 20000:
          if (lefwWriteEncrypt)
            encPrint(lefwFile, (char *)"   DATABASE MICRONS %d ;\n", database);
          else
            fprintf(lefwFile, "   DATABASE MICRONS %d ;\n", databaseVal);
          break;
        default: return LEFW_BAD_DATA;
      }
    }
  
    lefwState = LEFW_UNITS;
    return LEFW_OK;
  }
  
  int lefwUnitsFrequency(double frequency) {  // required since only by itself
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_UNITS_START && lefwState != LEFW_UNITS)
      return LEFW_BAD_ORDER;
    if (!frequency)
      return LEFW_BAD_DATA;
  
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   FREQUENCY MEGAHERTZ %.11g ;\n", frequency);
    else
      fprintf(lefwFile, "   FREQUENCY MEGAHERTZ %.11g ;\n", frequency);
  
    lefwState = LEFW_UNITS;
    return LEFW_OK;
  }
  
  int lefwEndUnits() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_UNITS_START && lefwState != LEFW_UNITS)
      return LEFW_BAD_ORDER;
  
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"END UNITS\n\n");
    else
      fprintf(lefwFile, "END UNITS\n\n");
    lefwLines++;
    lefwState = LEFW_UNITS_END;
    return LEFW_OK;
  }
  
  int lefwStartLayer(const char *layerName, const char *type) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState == LEFW_LAYER_START || lefwState == LEFW_LAYER)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (lefwIsMaxviastack)
      return LEFW_BAD_ORDER;  // Layer after maximum stacked-via
    if (strcmp(type, "CUT") == 0)
      lefwIsCut = 1;
    else if (strcmp(type, "IMPLANT") == 0)  // IMPLANT is 5.5 syntax
      lefwIsImplant = 1;
    else if (strcmp(type, "MASTERSLICE") && strcmp(type, "OVERLAP") && strcmp(type, "IMPLANT"))  // IMPLANT is 5.5 syntax
      return LEFW_BAD_DATA;  // type is CUT, MASTERSLICE or OVERLAP only
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"LAYER %s\n", layerName);
      encPrint(lefwFile, (char *)"   TYPE %s ;\n", type);
    } else {
      fprintf(lefwFile, "LAYER %s\n", layerName);
      fprintf(lefwFile, "   TYPE %s ;\n", type);
    }
    lefwIsRouting = 0;
    lefwLines     = lefwLines + 2;
    lefwState     = LEFW_LAYER_START;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerCutSpacing(double spacing) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYER_START && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    if (lefwIsLayerCutSpacing)
      return LEFW_BAD_ORDER;
    if ((!lefwIsCut) && (!lefwIsImplant))
      return LEFW_BAD_DATA;
    // only cut & implant call this func
    if (spacing) {
      if (lefwWriteEncrypt) {
        encPrint(lefwFile, (char *)"   SPACING %.11g", spacing);
      } else {
        fprintf(lefwFile, "   SPACING %.11g", spacing);
      }
    } else
      return LEFW_BAD_ORDER;
  
    lefwLines++;
    lefwState             = LEFW_LAYER;
    lefwIsLayerCutSpacing = 1;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerCutSpacingCenterToCenter() {
    if (!lefwIsLayerCutSpacing)
      return LEFW_BAD_ORDER;  // has to be after
    // lefwLayerCutSpacing is called
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"\n     CENTERTOCENTER");
    else
      fprintf(lefwFile, "\n     CENTERTOCENTER");
    lefwLines++;
  
    lefwState = LEFW_LAYER;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerCutSpacingSameNet() {
    if (!lefwIsLayerCutSpacing)
      return LEFW_BAD_ORDER;  // has to be after
    // lefwLayerCutSpacing is called
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"\n     SAMENET");
    else
      fprintf(lefwFile, "\n     SAMENET");
    lefwLines++;
  
    lefwState = LEFW_LAYER;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerCutSpacingLayer(const char *name2,
                               int         stack) {  // optional
    if (!lefwIsLayerCutSpacing)
      return LEFW_BAD_ORDER;  // has to be after
    // lefwLayerCutSpacing is called
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"\n     LAYER %s", name2);
      if (stack)
        encPrint(lefwFile, (char *)" STACK");
    } else {
      fprintf(lefwFile, "\n     LAYER %s", name2);
      if (stack)
        fprintf(lefwFile, " STACK");
    }
  
    lefwLines++;
    lefwState = LEFW_LAYER;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerCutSpacingAdjacent(int    viaCuts,  // either 2, 3 or 4, optional
                                  double distance,
                                  int    except) {  // optional
    if (!lefwIsLayerCutSpacing)
      return LEFW_BAD_ORDER;  // has to be after
    // lefwLayerCutSpacing is called
    if (lefwWriteEncrypt) {
      if (viaCuts < 2 && viaCuts > 4)
        return LEFW_BAD_DATA;
      encPrint(lefwFile, (char *)"\n     ADJACENTCUTS %d WITHIN %.11g", viaCuts, distance);
      if (except)
        encPrint(lefwFile, (char *)" EXCEPTSAMEPGNET");
  
    } else {
      if (viaCuts < 2 && viaCuts > 4)
        return LEFW_BAD_DATA;
      fprintf(lefwFile, "\n     ADJACENTCUTS %d WITHIN %.11g", viaCuts, distance);
      if (except)
        fprintf(lefwFile, " EXCEPTSAMEPGNET");
    }
  
    lefwLines++;
    lefwState = LEFW_LAYER;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerCutSpacingParallel() {
    if (!lefwIsLayerCutSpacing)
      return LEFW_BAD_ORDER;  // has to be after
    // lefwLayerCutSpacing is called
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"\n     PARALLELOVERLAP");
    } else {
      fprintf(lefwFile, "\n     PARALLELOVERLAP");
    }
  
    lefwLines++;
    lefwState = LEFW_LAYER;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerCutSpacingArea(double cutArea) {
    if (!lefwIsLayerCutSpacing)
      return LEFW_BAD_ORDER;  // has to be after
    // lefwLayerCutSpacing is called
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"\n     AREA %.11g", cutArea);
    } else {
      fprintf(lefwFile, "\n     AREA %.11g", cutArea);
    }
  
    lefwLines++;
    lefwState = LEFW_LAYER;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerCutSpacingEnd() {
    if (!lefwIsLayerCutSpacing)
      return LEFW_BAD_ORDER;  // has to be after
    // lefwLayerCutSpacing is called
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)" ;\n");
    } else {
      fprintf(lefwFile, " ;\n");
    }
  
    lefwIsLayerCutSpacing = 0;
    lefwLines++;
    lefwState = LEFW_LAYER;
    return LEFW_OK;
  }
  
  int lefwLayerMask(int colorMask) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYER_START && lefwState != LEFW_LAYER && lefwState != LEFW_LAYERROUTING_START)
      return LEFW_BAD_ORDER;
  
    if (versionNum < 5.8) {
      return LEFW_WRONG_VERSION;
    }
  
    if (!lefwValidateMaskNumber(colorMask)) {
      return LEFW_BAD_DATA;
    }
  
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   MASK %d ;\n", colorMask);
    else
      fprintf(lefwFile, "   MASK %d ;\n", colorMask);
  
    lefwLines++;
  
    lefwState = (lefwState == LEFW_LAYERROUTING_START) ? LEFW_LAYERROUTING : LEFW_LAYER;
  
    return LEFW_OK;
  }
  
  int lefwLayerWidth(double minWidth) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYER_START && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    if ((!lefwIsImplant) && (!lefwIsCut))
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   WIDTH %.11g ;\n", minWidth);
    else
      fprintf(lefwFile, "   WIDTH %.11g ;\n", minWidth);
  
    lefwLines++;
    lefwState = LEFW_LAYER;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerCutSpacingTableOrtho(int numSpacing, double *cutWithins, double *orthoSpacings) {
    int i;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYER_START && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    if (!lefwIsCut)
      return LEFW_BAD_DATA;  // only cut calls this func
    if (lefwIsMaxviastack)
      return LEFW_BAD_ORDER;  // Layer after maximum stacked-via
    if (numSpacing) {
      if (lefwWriteEncrypt) {
        encPrint(lefwFile, (char *)"   SPACINGTABLE ORTHOGONAL");
        lefwLines++;
        for (i = 0; i < numSpacing; i++) {
          encPrint(lefwFile, (char *)"\n     WITHING %.11g SPACING %.11g ", *cutWithins++, *orthoSpacings++);
          lefwLines++;
        }
        encPrint(lefwFile, (char *)" ;\n");
      } else {
        fprintf(lefwFile, "   SPACINGTABLE ORTHOGONAL");
        lefwLines++;
        for (i = 0; i < numSpacing; i++) {
          fprintf(lefwFile, "\n     WITHIN %.11g SPACING %.11g", *cutWithins++, *orthoSpacings++);
          lefwLines++;
        }
        fprintf(lefwFile, " ;\n");
      }
    }
    lefwState = LEFW_LAYER;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerArraySpacing(int longArray, double viaWidth, double cutSpacing, int numArrayCut, int *arrayCuts,
                            double *arraySpacings) {
    int i;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYER_START && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    if (!lefwIsCut)
      return LEFW_BAD_DATA;  // only cut calls this func
    if (lefwIsMaxviastack)
      return LEFW_BAD_ORDER;  // Layer after maximum stacked-via
    if (cutSpacing) {
      if (lefwWriteEncrypt) {
        encPrint(lefwFile, (char *)"   ARRAYSPACING ");
        if (longArray)
          encPrint(lefwFile, (char *)"LONGARRAY ");
        if (viaWidth)
          encPrint(lefwFile, (char *)"WIDTH %.11g ", viaWidth);
        encPrint(lefwFile, (char *)"CUTSPACING %.11g ", cutSpacing);
        for (i = 0; i < numArrayCut; i++) {
          encPrint(lefwFile, (char *)"ARRAYCUTS %d SPACING %.11g ", *arrayCuts++, *arraySpacings++);
        }
        encPrint(lefwFile, (char *)" ;\n");
      } else {
        fprintf(lefwFile, "  ARRAYSPACING ");
        if (longArray)
          fprintf(lefwFile, "LONGARRAY ");
        if (viaWidth)
          fprintf(lefwFile, "WIDTH %.11g ", viaWidth);
        fprintf(lefwFile, "CUTSPACING %.11g ", cutSpacing);
        for (i = 0; i < numArrayCut; i++) {
          fprintf(lefwFile, "ARRAYCUTS %d SPACING %.11g ", *arrayCuts++, *arraySpacings++);
        }
        fprintf(lefwFile, " ;\n");
      }
      lefwLines++;
    }
    lefwState = LEFW_LAYER;
    return LEFW_OK;
  }
  
  int lefwLayerEnclosure(const char *location, double overhang1, double overhang2,
                         double width) {  // optional
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYER_START && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    if (!lefwIsCut)
      return LEFW_BAD_DATA;  // only cut calls this func
    if (lefwIsMaxviastack)
      return LEFW_BAD_ORDER;  // Layer after maximum stacked-via
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   ENCLOSURE ");
      if (location && (*location != 0)) {
        if (strcmp(location, "ABOVE") && strcmp(location, "BELOW")) {
          encPrint(lefwFile, (char *)"ENCLOSURE in Layer(Cut) can only be ABOVE, BELOW.\n");
          return LEFW_BAD_DATA;
        }
        encPrint(lefwFile, (char *)"%s ", location);
      }
      encPrint(lefwFile, (char *)"%.11g %.11g ", overhang1, overhang2);
      if (width)
        encPrint(lefwFile, (char *)"WIDTH %.11g ", width);
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "   ENCLOSURE ");
      if (location && (*location != 0)) {
        if (strcmp(location, "ABOVE") && strcmp(location, "BELOW")) {
          fprintf(lefwFile, "ENCLOSURE in Layer(Cut) can only be ABOVE, BELOW.\n");
          return LEFW_BAD_DATA;
        }
        fprintf(lefwFile, "%s ", location);
      }
      fprintf(lefwFile, "%.11g %.11g ", overhang1, overhang2);
      if (width)
        fprintf(lefwFile, "WIDTH %.11g ", width);
      fprintf(lefwFile, ";\n");
    }
    lefwLines++;
    lefwState = LEFW_LAYER;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerEnclosureWidth(const char *location, double overhang1, double overhang2,
                              double width,        // optional
                              double cutWithin) {  // optional
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYER_START && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    if (!lefwIsCut)
      return LEFW_BAD_DATA;  // only cut calls this func
    if (lefwIsMaxviastack)
      return LEFW_BAD_ORDER;  // Layer after maximum stacked-via
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   ENCLOSURE ");
      if (location && (*location != 0)) {
        if (strcmp(location, "ABOVE") && strcmp(location, "BELOW")) {
          encPrint(lefwFile, (char *)"ENCLOSURE in Layer(Cut) can only be ABOVE, BELOW.\n");
          return LEFW_BAD_DATA;
        }
        encPrint(lefwFile, (char *)"%s ", location);
      }
      encPrint(lefwFile, (char *)"%.11g %.11g ", overhang1, overhang2);
      if (width) {
        encPrint(lefwFile, (char *)"WIDTH %.11g ", width);
        if (cutWithin)
          encPrint(lefwFile, (char *)"EXCEPTEXTRACUT %.11g ", cutWithin);
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "   ENCLOSURE ");
      if (location && (*location != 0)) {
        if (strcmp(location, "ABOVE") && strcmp(location, "BELOW")) {
          fprintf(lefwFile, "ENCLOSURE in Layer(Cut) can only be ABOVE, BELOW.\n");
          return LEFW_BAD_DATA;
        }
        fprintf(lefwFile, "%s ", location);
      }
      fprintf(lefwFile, "%.11g %.11g ", overhang1, overhang2);
      if (width) {
        fprintf(lefwFile, "WIDTH %.11g ", width);
        if (cutWithin)
          fprintf(lefwFile, "EXCEPTEXTRACUT %.11g ", cutWithin);
      }
      fprintf(lefwFile, ";\n");
    }
    lefwLines++;
    lefwState = LEFW_LAYER;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerEnclosureLength(const char *location, double overhang1, double overhang2,
                               double minLength) {  // optional
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYER_START && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    if (!lefwIsCut)
      return LEFW_BAD_DATA;  // only cut calls this func
    if (lefwIsMaxviastack)
      return LEFW_BAD_ORDER;  // Layer after maximum stacked-via
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   ENCLOSURE ");
      if (location && (*location != 0)) {
        if (strcmp(location, "ABOVE") && strcmp(location, "BELOW")) {
          encPrint(lefwFile, (char *)"ENCLOSURE in Layer(Cut) can only be ABOVE, BELOW.\n");
          return LEFW_BAD_DATA;
        }
        encPrint(lefwFile, (char *)"%s ", location);
      }
      encPrint(lefwFile, (char *)"%.11g %.11g ", overhang1, overhang2);
      if (minLength)
        encPrint(lefwFile, (char *)"LENGTH %.11g ", minLength);
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "   ENCLOSURE ");
      if (location && (*location != 0)) {
        if (strcmp(location, "ABOVE") && strcmp(location, "BELOW")) {
          fprintf(lefwFile, "ENCLOSURE in Layer(Cut) can only be ABOVE, BELOW.\n");
          return LEFW_BAD_DATA;
        }
        fprintf(lefwFile, "%s ", location);
      }
      fprintf(lefwFile, "%.11g %.11g ", overhang1, overhang2);
      if (minLength)
        fprintf(lefwFile, "LENGTH %.11g ", minLength);
      fprintf(lefwFile, ";\n");
    }
    lefwLines++;
    lefwState = LEFW_LAYER;
    return LEFW_OK;
  }
  
  int lefwLayerPreferEnclosure(const char *location, double overhang1, double overhang2,
                               double width) {  // optional
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYER_START && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    if (!lefwIsCut)
      return LEFW_BAD_DATA;  // only cut calls this func
    if (lefwIsMaxviastack)
      return LEFW_BAD_ORDER;  // Layer after maximum stacked-via
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   PREFERENCLOSURE ");
      if (location && (*location != 0)) {
        if (strcmp(location, "ABOVE") && strcmp(location, "BELOW")) {
          encPrint(lefwFile, (char *)"PREFERENCLOSURE in Layer(Cut) can only be ABOVE, BELOW.\n");
          return LEFW_BAD_DATA;
        }
        encPrint(lefwFile, (char *)"%s ", location);
      }
      encPrint(lefwFile, (char *)"%.11g %.11g ", overhang1, overhang2);
      if (width)
        encPrint(lefwFile, (char *)"WIDTH %.11g ", width);
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "   PREFERENCLOSURE ");
      if (location && (*location != 0)) {
        if (strcmp(location, "ABOVE") && strcmp(location, "BELOW")) {
          fprintf(lefwFile, "PREFERENCLOSURE in Layer(Cut) can only be ABOVE, BELOW.\n");
          return LEFW_BAD_DATA;
        }
        fprintf(lefwFile, "%s ", location);
      }
      fprintf(lefwFile, "%.11g %.11g ", overhang1, overhang2);
      if (width)
        fprintf(lefwFile, "WIDTH %.11g ", width);
      fprintf(lefwFile, ";\n");
    }
    lefwLines++;
    lefwState = LEFW_LAYER;
    return LEFW_OK;
  }
  
  int lefwLayerResistancePerCut(double resistance) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYER_START && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    if (!lefwIsCut)
      return LEFW_BAD_DATA;  // only cut calls this func
    if (lefwIsMaxviastack)
      return LEFW_BAD_ORDER;  // Layer after maximum stacked-via
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   RESISTANCEPERCUT %.11g ;\n", resistance);
    else
      fprintf(lefwFile, "   RESISTANCEPERCUT %.11g ;\n", resistance);
    lefwLines++;
    lefwState = LEFW_LAYER;
    return LEFW_OK;
  }
  
  int lefwEndLayer(const char *layerName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYER_START && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"END %s\n\n", layerName);
    else
      fprintf(lefwFile, "END %s\n\n", layerName);
  
    lefwLines++;
    lefwState     = LEFW_LAYER_END;
    lefwIsCut     = 0;
    lefwIsImplant = 0;
    return LEFW_OK;
  }
  
  int lefwStartLayerRouting(const char *layerName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState == LEFW_LAYERROUTING_START || lefwState == LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"LAYER %s\n", layerName);
      encPrint(lefwFile, (char *)"   TYPE ROUTING ;\n");
    } else {
      fprintf(lefwFile, "LAYER %s\n", layerName);
      fprintf(lefwFile, "   TYPE ROUTING ;\n");
    }
    lefwIsRouting                         = 1;
    lefwIsRoutingReqData                  = 0;
    lefwLines                             = lefwLines + 2;
    lefwState                             = LEFW_LAYERROUTING_START;
    lefwSynArray[LEFW_LAYERROUTING_START] = 1;
  
    return LEFW_OK;
  }
  
  int lefwLayerRouting(const char *direction, double width) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    // this routine should call only once per layer routing
    if (lefwSynArray[LEFW_LAYERROUTING])
      return LEFW_ALREADY_DEFINED;
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt) {
      if (!direction || direction == 0 || *direction == 0) {
        encPrint(lefwFile, (char *)"DIRECTION is required in Layer(Routing).\n");
        return LEFW_BAD_DATA;
      }
      if (strcmp(direction, "HORIZONTAL") && strcmp(direction, "VERTICAL") && strcmp(direction, "DIAG45")
          && strcmp(direction, "DIAG135")) {
        encPrint(lefwFile, (char *)"DIRECTION in Layer(Routing) can only be HORIZONTAL, VERTICAL, DIAG45, DIAG135.\n");
        return LEFW_BAD_DATA;  // direction is either HORIZONTAL, VERTICAL, DIAG45, DIAG135 only
      }
      encPrint(lefwFile, (char *)"   DIRECTION %s ;\n", direction);
      encPrint(lefwFile, (char *)"   WIDTH %.11g ;\n", width);
    } else {
      if (!direction || direction == 0 || *direction == 0) {
        fprintf(lefwFile, "DIRECTION is required in Layer(Routing).\n");
        return LEFW_BAD_DATA;
      }
      if (strcmp(direction, "HORIZONTAL") && strcmp(direction, "VERTICAL") && strcmp(direction, "DIAG45")
          && strcmp(direction, "DIAG135")) {
        fprintf(lefwFile, "DIRECTION in Layer(Routing) can only be HORIZONTAL, VERTICAL, DIAG45, DIAG135.\n");
        return LEFW_BAD_DATA;  // direction is either HORIZONTAL, VERTICAL, DIAG45, DIAG135 only
      }
      fprintf(lefwFile, "   DIRECTION %s ;\n", direction);
      fprintf(lefwFile, "   WIDTH %.11g ;\n", width);
    }
  
    lefwLines += 2;
    lefwIsRoutingReqData            = 1;
    lefwSynArray[LEFW_LAYERROUTING] = 1;
    lefwIsRoutingMinCut             = 0;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingPitch(double pitch) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    // this routine should call only once per layer routing
    // it is required for SE only, other is optional
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   PITCH %.11g ;\n", pitch);
    else
      fprintf(lefwFile, "   PITCH %.11g ;\n", pitch);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingPitchXYDistance(double xDistance, double yDistance) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    // this routine should call only once per layer routing
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   PITCH %.11g %.11g ;\n", xDistance, yDistance);
    else
      fprintf(lefwFile, "   PITCH %.11g %.11g ;\n", xDistance, yDistance);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingOffset(double offset) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   OFFSET %.11g ;\n", offset);
    else
      fprintf(lefwFile, "   OFFSET %.11g ;\n", offset);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingOffsetXYDistance(double xDistance, double yDistance) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   OFFSET %.11g %.11g ;\n", xDistance, yDistance);
    else
      fprintf(lefwFile, "   OFFSET %.11g %.11g ;\n", xDistance, yDistance);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingDiagPitch(double distance) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   DIAGPITCH %.11g ;\n", distance);
    else
      fprintf(lefwFile, "   DIAGPITCH %.11g ;\n", distance);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingDiagPitchXYDistance(double xDistance, double yDistance) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   DIAGPITCH %.11g %.11g ;\n", xDistance, yDistance);
    else
      fprintf(lefwFile, "   DIAGPITCH %.11g %.11g ;\n", xDistance, yDistance);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingDiagWidth(double diagWidth) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    // this routine should call only once per layer routing
    // it is required for SE only, other is optional
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   DIAGWIDTH %.11g ;\n", diagWidth);
    else
      fprintf(lefwFile, "   DIAGWIDTH %.11g ;\n", diagWidth);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingDiagSpacing(double diagSpacing) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    // this routine should call only once per layer routing
    // it is required for SE only, other is optional
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   DIAGSPACING %.11g ;\n", diagSpacing);
    else
      fprintf(lefwFile, "   DIAGSPACING %.11g ;\n", diagSpacing);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingDiagMinEdgeLength(double diagLength) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    // this routine should call only once per layer routing
    // it is required for SE only, other is optional
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   DIAGMINEDGELENGTH %.11g ;\n", diagLength);
    else
      fprintf(lefwFile, "   DIAGMINEDGELENGTH %.11g ;\n", diagLength);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingArea(double area) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   AREA %.11g ;\n", area);
    else
      fprintf(lefwFile, "   AREA %.11g ;\n", area);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingMinsize(int numRect, double *minWidth, double *minLength) {
    int i;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   MINSIZE ");
      for (i = 0; i < numRect; i++) encPrint(lefwFile, (char *)"%.11g %.11g ", minWidth[i], minLength[i]);
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "   MINSIZE ");
      for (i = 0; i < numRect; i++) fprintf(lefwFile, "%.11g %.11g ", minWidth[i], minLength[i]);
      fprintf(lefwFile, ";\n");
    }
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingMinimumcut(double numCuts, double minWidth) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   MINIMUMCUT %.11g WIDTH %.11g ", numCuts, minWidth);
    else
      fprintf(lefwFile, "   MINIMUMCUT %.11g WIDTH %.11g ", numCuts, minWidth);
    lefwLines++;
    prtSemiColon            = 1;
    lefwIsRoutingMinCut     = 1;
    lefwIsRoutingMinCutDist = 0;
    lefwIsRoutingMinCutLen  = 0;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerRoutingMinimumcutWithin(double numCuts, double minWidth, double cutDistance) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   MINIMUMCUT %.11g WIDTH %.11g WITHIN %.11g ", numCuts, minWidth, cutDistance);
    else
      fprintf(lefwFile, "   MINIMUMCUT %.11g WIDTH %.11g WITHIN %.11g ", numCuts, minWidth, cutDistance);
    lefwLines++;
    prtSemiColon            = 1;
    lefwIsRoutingMinCut     = 1;
    lefwIsRoutingMinCutDist = 0;
    lefwIsRoutingMinCutLen  = 0;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingMinimumcutConnections(const char *direction) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwIsRoutingMinCut || lefwIsRoutingMinCutDist)
      return LEFW_BAD_ORDER;
    // lefwLayerRoutingMinimumcut has not being called or
    // lefwLayerRoutingMinimumcutConnections has already called
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"\n     %s ", direction);
    else
      fprintf(lefwFile, "\n     %s ", direction);
    lefwLines++;
    prtSemiColon            = 1;
    lefwIsRoutingMinCutDist = 1;
    if (lefwIsRoutingMinCutLen)  // both distance & length within has defined
      lefwIsRoutingMinCut = 0;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingMinimumcutLengthWithin(double length, double distance) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwIsRoutingMinCut || lefwIsRoutingMinCutLen)
      return LEFW_BAD_ORDER;
    // lefwLayerRoutingMinimumcut has not being called or
    // lefwLayerRoutingMinimumcutLengthWithin has already called
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"     LENGTH %.11g WITHIN %.11g ", length, distance);
    else
      fprintf(lefwFile, "     LENGTH %.11g WITHIN %.11g ", length, distance);
    lefwLines++;
    prtSemiColon           = 1;
    lefwIsRoutingMinCutLen = 1;
    if (lefwIsRoutingMinCutDist)  // both distance & length within has defined
      lefwIsRoutingMinCut = 0;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingSpacing(double spacing) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   SPACING %.11g ", spacing);
    else
      fprintf(lefwFile, "   SPACING %.11g ", spacing);
    lefwLines++;
    lefwHasLayerRoutingRange   = 0;  // initialization
    lefwHasLayerRoutingSpacing = 1;  // initialization
    lefwHasLayerRoutingEol     = 0;  // initialization
    prtNewLine                 = 1;
    prtSemiColon               = 1;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingSpacingRange(double leftRange, double rightRange) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (!lefwHasLayerRoutingSpacing)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"RANGE %.11g %.11g ", leftRange, rightRange);
    else
      fprintf(lefwFile, "RANGE %.11g %.11g ", leftRange, rightRange);
    lefwHasLayerRoutingRange = 1;  // initialization
    lefwLines++;
    prtNewLine   = 1;
    prtSemiColon = 1;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingSpacingRangeUseLengthThreshold() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (!lefwHasLayerRoutingRange) {
      // This routine can be called only if range are non zero
      fprintf(lefwFile, "ERROR (LEFWRIT-4003): lefwLayerRoutingSpacingUseLengthThreshold cannot be called if\n");
      fprintf(lefwFile, "       lefwLayerRoutingSpacingRange has not been called.\n");
      return LEFW_BAD_DATA;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"\n     USELENGTHTHRESHOLD ");
    else
      fprintf(lefwFile, "\n     USELENGTHTHRESHOLD ");
    prtSemiColon             = 1;
    prtNewLine               = 1;
    lefwHasLayerRoutingRange = 0;  // reset to 0
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingSpacingRangeInfluence(double infValue, double subMinWidth, double subMaxWidth) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (!lefwHasLayerRoutingRange) {
      // This routine can be called only if range are non zero
      fprintf(lefwFile, "ERROR (LEFWRIT-4004): lefwLayerRoutingSpacingInfluence cannot be called if\n");
      fprintf(lefwFile, "       lefRange and rightRange in lefwLayerRoutingSpacing are both zero.\n");
      return LEFW_BAD_DATA;
    }
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"\n     INFLUENCE %.11g ", infValue);
      if (subMinWidth || subMaxWidth)
        encPrint(lefwFile, (char *)"RANGE %.11g %.11g ", subMinWidth, subMaxWidth);
    } else {
      fprintf(lefwFile, "\n     INFLUENCE %.11g ", infValue);
      if (subMinWidth || subMaxWidth)
        fprintf(lefwFile, (char *)"RANGE %.11g %.11g ", subMinWidth, subMaxWidth);
    }
    prtNewLine               = 1;
    prtSemiColon             = 1;
    lefwHasLayerRoutingRange = 0;  // reset to 0
    return LEFW_OK;
  }
  
  int lefwLayerRoutingSpacingRangeRange(double minWidth, double maxWidth) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (!lefwHasLayerRoutingRange) {
      // This routine can be called only if range are non zero
      fprintf(lefwFile, "ERROR (LEFWRIT-4005): lefwLayerRoutingSpacingInfluence cannot be called if\n");
      fprintf(lefwFile, "       lefRange and rightRange in lefwLayerRoutingSpacing are both zero.\n");
      return LEFW_BAD_DATA;
    }
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"RANGE %.11g %.11g ", minWidth, maxWidth);
    } else {
      fprintf(lefwFile, (char *)"RANGE %.11g %.11g ", minWidth, maxWidth);
    }
    prtNewLine               = 1;
    prtSemiColon             = 1;
    lefwHasLayerRoutingRange = 0;  // reset to 0
    return LEFW_OK;
  }
  
  int lefwLayerRoutingSpacingLengthThreshold(double lengthValue, double minWidth, double maxWidth) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (!lefwHasLayerRoutingSpacing)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   LENGTHTHRESHOLD %.11g ", lengthValue);
      if (minWidth || maxWidth) {
        encPrint(lefwFile, (char *)"RANGE %.11g %.11g ", minWidth, maxWidth);
      }
    } else {
      fprintf(lefwFile, "   LENGTHTHRESHOLD %.11g ", lengthValue);
      if (minWidth || maxWidth) {
        fprintf(lefwFile, "RANGE %.11g %.11g ", minWidth, maxWidth);
      }
    }
    prtSemiColon = 1;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerRoutingSpacingSameNet(int PGOnly) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (!lefwHasLayerRoutingSpacing)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt) {
      if (PGOnly)
        encPrint(lefwFile, (char *)"   SAMENET PGONLY ");
      else
        encPrint(lefwFile, (char *)"   SAMENET ");
    } else {
      if (PGOnly)
        fprintf(lefwFile, "   SAMENET PGONLY ");
      else
        fprintf(lefwFile, "   SAMENET ");
    }
    prtSemiColon = 1;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerRoutingSpacingEndOfLine(double eolWidth, double eolWithin) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (lefwHasLayerRoutingEol)
      return LEFW_BAD_DATA;  // already defined in Spacing
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ENDOFLINE %.11g WITHIN %.11g ", eolWidth, eolWithin);
    else
      fprintf(lefwFile, "   ENDOFLINE %.11g WITHIN %.11g ", eolWidth, eolWithin);
    lefwLines++;
    lefwHasLayerRoutingEol = 1;
    prtSemiColon           = 1;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerRoutingSpacingEOLParallel(double parSpace, double parWithin, int twoEdges) {
    if (!lefwHasLayerRoutingEol)
      return LEFW_BAD_DATA;  // EndOfLine in not defined
    if (lefwWriteEncrypt) {
      if (twoEdges)
        encPrint(lefwFile, (char *)"PARALLELEDGE %.11g WITHIN %.11g TWOEDGES ;\n", parSpace, parWithin);
      else
        encPrint(lefwFile, (char *)"PARALLELEDGE %.11g WITHIN %.11g ;\n", parSpace, parWithin);
    } else {
      if (twoEdges)
        fprintf(lefwFile, "PARALLELEDGE %.11g WITHIN %.11g TWOEDGES ;\n", parSpace, parWithin);
      else
        fprintf(lefwFile, "PARALLELEDGE %.11g WITHIN %.11g ;\n", parSpace, parWithin);
    }
    lefwLines++;
    lefwHasLayerRoutingEol = 0;
    prtSemiColon           = 0;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerRoutingSpacingNotchLength(double minNLength) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   NOTCHLENGTH %.11g ;\n", minNLength);
    else
      fprintf(lefwFile, "   NOTCHLENGTH %.11g ;\n", minNLength);
    lefwLines++;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerRoutingSpacingEndOfNotchWidth(double eonWidth, double minNSpacing, double minNLength) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile,
               (char *)"   ENDOFNOTCHWIDTH %.11g NOTCHSPACING %.11g NOTCHLENGTH %.11g ;\n",
               eonWidth,
               minNSpacing,
               minNLength);
    else
      fprintf(lefwFile, "    ENDOFNOTCHWIDTH %.11g NOTCHSPACING %.11g NOTCHLENGTH %.11g ;\n", eonWidth, minNSpacing, minNLength);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingWireExtension(double wireExtension) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   WIREEXTENSION %.11g ;\n", wireExtension);
    else
      fprintf(lefwFile, "   WIREEXTENSION %.11g ;\n", wireExtension);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingResistance(const char *resistance) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (!resistance || resistance == 0 || *resistance == 0)
      return LEFW_BAD_DATA;
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   RESISTANCE RPERSQ %s ;\n", resistance);
    else
      fprintf(lefwFile, "   RESISTANCE RPERSQ %s ;\n", resistance);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingCapacitance(const char *capacitance) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (!capacitance || capacitance == 0 || *capacitance == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   CAPACITANCE CPERSQDIST %s ;\n", capacitance);
    else
      fprintf(lefwFile, "   CAPACITANCE CPERSQDIST %s ;\n", capacitance);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingHeight(double height) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   HEIGHT %.11g ;\n", height);
    else
      fprintf(lefwFile, "   HEIGHT %.11g ;\n", height);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingThickness(double thickness) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   THICKNESS %.11g ;\n", thickness);
    else
      fprintf(lefwFile, "   THICKNESS %.11g ;\n", thickness);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingShrinkage(double shrinkage) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   SHRINKAGE %.11g ;\n", shrinkage);
    else
      fprintf(lefwFile, "   SHRINKAGE %.11g ;\n", shrinkage);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingCapMultiplier(double capMultiplier) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   CAPMULTIPLIER %.11g ;\n", capMultiplier);
    else
      fprintf(lefwFile, "   CAPMULTIPLIER %.11g ;\n", capMultiplier);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingEdgeCap(double edgeCap) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   EDGECAPACITANCE %.11g ;\n", edgeCap);
    else
      fprintf(lefwFile, "   EDGECAPACITANCE %.11g ;\n", edgeCap);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingAntennaArea(double antennaArea) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ANTENNAAREAFACTOR %.11g ;\n", antennaArea);
    else
      fprintf(lefwFile, "   ANTENNAAREAFACTOR %.11g ;\n", antennaArea);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingAntennaLength(double antennaLength) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ANTENNALENGTHFACTOR %.11g ;\n", antennaLength);
    else
      fprintf(lefwFile, "   ANTENNALENGTHFACTOR %.11g ;\n", antennaLength);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingMaxwidth(double width) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   MAXWIDTH %.11g ;\n", width);
    else
      fprintf(lefwFile, "   MAXWIDTH %.11g ;\n", width);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingMinwidth(double width) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   MINWIDTH %.11g ;\n", width);
    else
      fprintf(lefwFile, "   MINWIDTH %.11g ;\n", width);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingMinenclosedarea(int numMinenclosed, double *area, double *width) {
    int i;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt) {
      for (i = 0; i < numMinenclosed; i++) {
        encPrint(lefwFile, (char *)"   MINENCLOSEDAREA %.11g ", area[i]);
        if (width[i] != 0)
          encPrint(lefwFile, (char *)"WIDTH %.11g ", width[i]);
        encPrint(lefwFile, (char *)";\n");
      }
    } else {
      for (i = 0; i < numMinenclosed; i++) {
        fprintf(lefwFile, "   MINENCLOSEDAREA %.11g ", area[i]);
        if (width[i] != 0)
          fprintf(lefwFile, "WIDTH %.11g ", width[i]);
        fprintf(lefwFile, ";\n");
      }
    }
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingMinstep(double distance) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   MINSTEP %.11g ;\n", distance);
    else
      fprintf(lefwFile, "   MINSTEP %.11g ;\n", distance);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingMinstepWithOptions(double distance, const char *rule, double maxLength) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   MINSTEP %.11g ", distance);
    else
      fprintf(lefwFile, "   MINSTEP %.11g ", distance);
    if (rule && ((strcmp(rule, "INSIDECORNER") == 0) || (strcmp(rule, "OUTSIDECORNER") == 0) || (strcmp(rule, "STEP") == 0))) {
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)"%s ", rule);
      else
        fprintf(lefwFile, "%s ", rule);
    }
    if (maxLength) {
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)"LENGTHSUM %.11g ", maxLength);
      else
        fprintf(lefwFile, "LENGTHSUM %.11g ", maxLength);
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)";\n");
    else
      fprintf(lefwFile, ";\n");
    lefwLines++;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerRoutingMinstepMaxEdges(double distance, double maxEdges) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   MINSTEP %.11g MAXEDGES %.11g ;\n", distance, maxEdges);
    else
      fprintf(lefwFile, "   MINSTEP %.11g MAXEDGES %.11g ;\n", distance, maxEdges);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingProtrusion(double width1, double length, double width2) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;  // only routing calls this func
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   PROTRUSIONWIDTH %.11g LENGTH %.11g WIDTH %.11g ;\n", width1, length, width2);
    else
      fprintf(lefwFile, "   PROTRUSIONWIDTH %.11g LENGTH %.11g WIDTH %.11g ;\n", width1, length, width2);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingStartSpacingtableParallel(int numLength, double *length) {
    int i;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRoutingReqData) {
      return LEFW_BAD_ORDER;
    }
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   SPACINGTABLE\n");
      encPrint(lefwFile, (char *)"     PARALLELRUNLENGTH");
      for (i = 0; i < numLength; i++) encPrint(lefwFile, (char *)" %.11g", length[i]);
    } else {
      fprintf(lefwFile, "   SPACINGTABLE\n");
      fprintf(lefwFile, "     PARALLELRUNLENGTH");
      for (i = 0; i < numLength; i++) fprintf(lefwFile, " %.11g", length[i]);
    }
    lefwState = LEFW_LAYERROUTING_SP_START;
    lefwLines += 2;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingSpacingtableParallelWidth(double width, int numSpacing, double *spacing) {
    int i;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_SP_START && lefwState != LEFW_LAYERROUTINGWIDTH)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"\n       WIDTH %.11g", width);
      for (i = 0; i < numSpacing; i++) encPrint(lefwFile, (char *)" %.11g", spacing[i]);
    } else {
      fprintf(lefwFile, "\n       WIDTH %.11g", width);
      for (i = 0; i < numSpacing; i++) fprintf(lefwFile, " %.11g", spacing[i]);
    }
    lefwState = LEFW_LAYERROUTINGWIDTH;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingStartSpacingtableInfluence() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRoutingReqData) {
      return LEFW_BAD_ORDER;
    }
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   SPACINGTABLE\n");
      encPrint(lefwFile, (char *)"     INFLUENCE");
    } else {
      fprintf(lefwFile, "   SPACINGTABLE\n");
      fprintf(lefwFile, "     INFLUENCE");
    }
    lefwState = LEFW_LAYERROUTINGWIDTH;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingSpacingInfluenceWidth(double width, double distance, double spacing) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTINGWIDTH)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"\n       WIDTH %.11g WITHIN %.11%.11gSPACING %.11g", width, distance, spacing);
    else
      fprintf(lefwFile, "\n       WIDTH %.11g WITHIN %.11g SPACING %.11g", width, distance, spacing);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingStartSpacingtableTwoWidths() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRoutingReqData) {
      return LEFW_BAD_ORDER;
    }
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   SPACINGTABLE\n");
      encPrint(lefwFile, (char *)"     TWOWIDTHS");
    } else {
      fprintf(lefwFile, "   SPACINGTABLE\n");
      fprintf(lefwFile, "     TWOWIDTHS");
    }
    lefwState = LEFW_LAYERROUTINGWIDTH;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutingSpacingtableTwoWidthsWidth(double width, double runLength, int numSpacing, double *spacing) {
    int i;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_SP_START && lefwState != LEFW_LAYERROUTINGWIDTH)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"\n       WIDTH %.11g", width);
      if (runLength)
        encPrint(lefwFile, (char *)" PRL %.11g", runLength);
      for (i = 0; i < numSpacing; i++) encPrint(lefwFile, (char *)" %.11g", spacing[i]);
    } else {
      fprintf(lefwFile, "\n       WIDTH %.11g", width);
      if (runLength)
        fprintf(lefwFile, " PRL %.11g", runLength);
      for (i = 0; i < numSpacing; i++) fprintf(lefwFile, " %.11g", spacing[i]);
    }
    lefwState = LEFW_LAYERROUTINGWIDTH;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerRoutineEndSpacingtable() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTINGWIDTH)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)" ;\n");
    else
      fprintf(lefwFile, " ;\n");
  
    lefwLines++;
    lefwState = LEFW_LAYERROUTING;
    return LEFW_OK;
  }
  
  int lefwEndLayerRouting(const char *layerName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    if (!lefwIsRoutingReqData) {
      return LEFW_BAD_ORDER;
    }
    if (prtSemiColon) {
      // the previous statement hasn't written the ; yet
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)";\n");
      else
        fprintf(lefwFile, ";\n");
      prtSemiColon = 0;
    }
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"END %s\n\n", layerName);
    else
      fprintf(lefwFile, "END %s\n\n", layerName);
  
    lefwLines++;
    lefwSynArray[LEFW_LAYERROUTING] = 0;
    lefwState                       = LEFW_LAYERROUTING_END;
    lefwIsRouting                   = 0;
    return LEFW_OK;
  }
  
  int lefwLayerACCurrentDensity(const char *type, double value) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING && lefwState != LEFW_LAYER_START
        && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    if (strcmp(type, "PEAK") && strcmp(type, "AVERAGE") && strcmp(type, "RMS"))
      return LEFW_BAD_DATA;  // type is PEAK, AVERAGE & RMS only
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   ACCURRENTDENSITY %s", type);
      lefwLines++;
      lefwTableLen = 5;
      if (value)
        encPrint(lefwFile, (char *)" %.11g ;\n", value);
      // that's it for accurrentdensity
      else {
        encPrint(lefwFile, (char *)"\n");
        // expect to have frequency & tableentries
        lefwOldState = lefwState;  // save the previous state
        lefwState    = LEFW_LAYERACCURRENT;
      }
    } else {
      fprintf(lefwFile, "   ACCURRENTDENSITY %s", type);
      lefwLines++;
      lefwTableLen = 5;
      if (value)
        fprintf(lefwFile, " %.11g ;\n", value);  // that's it for accurrentdensity
      else {
        fprintf(lefwFile, "\n");   //  expect to have frequency & tableentries
        lefwOldState = lefwState;  // save the previous state
        lefwState    = LEFW_LAYERACCURRENT;
      }
    }
    return LEFW_OK;
  }
  
  int lefwLayerACFrequency(int numFrequency, double *frequency) {
    int i;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERACCURRENT)
      return LEFW_BAD_ORDER;
  
    if (numFrequency <= 0)
      return LEFW_BAD_DATA;  // frequency are required
  
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      FREQUENCY ");
      for (i = 0; i < numFrequency; i++) {
        encPrint(lefwFile, (char *)"%.11g ", *frequency++);
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      FREQUENCY ");
      for (i = 0; i < numFrequency; i++) {
        fprintf(lefwFile, "%.11g ", *frequency++);
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerACWidth(int numWidths, double *widths) {
    int i;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERACCURRENT)
      return LEFW_BAD_ORDER;
  
    if (numWidths <= 0)
      return LEFW_OK;  // width is optional
  
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      WIDTH ");
      for (i = 0; i < numWidths; i++) {
        encPrint(lefwFile, (char *)"%.11g ", *widths++);
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      WIDTH ");
      for (i = 0; i < numWidths; i++) {
        fprintf(lefwFile, "%.11g ", *widths++);
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwTableLen = numWidths;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerACCutarea(int numCutareas, double *cutareas) {
    int i;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERACCURRENT)
      return LEFW_BAD_ORDER;
  
    if (numCutareas <= 0)
      return LEFW_OK;  // cutarea is optional
  
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      CUTAREA ");
      for (i = 0; i < numCutareas; i++) {
        encPrint(lefwFile, (char *)"%.11g ", *cutareas++);
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      CUTAREA ");
      for (i = 0; i < numCutareas; i++) {
        fprintf(lefwFile, "%.11g ", *cutareas++);
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwTableLen = numCutareas;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerACTableEntries(int numEntries, double *entries) {
    int i;
    int j = 0;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERACCURRENT)
      return LEFW_BAD_ORDER;
  
    if (numEntries <= 0)
      return LEFW_BAD_DATA;  // tableEntries are required
  
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      TABLEENTRIES\n        ");
      for (i = 0; i < numEntries; i++) {
        if (++j > lefwTableLen) {
          encPrint(lefwFile, (char *)"\n        ");
          j = 1;
        }
        encPrint(lefwFile, (char *)"%.11g ", *entries++);
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      TABLEENTRIES\n        ");
      for (i = 0; i < numEntries; i++) {
        if (++j > lefwTableLen) {
          fprintf(lefwFile, "\n        ");
          j = 1;
        }
        fprintf(lefwFile, "%.11g ", *entries++);
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwState = lefwOldState;  // restore the previous state
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerDCCurrentDensity(const char *type, double value) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING && lefwState != LEFW_LAYER_START
        && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    if (strcmp(type, "AVERAGE"))
      return LEFW_BAD_DATA;  // type is AVERAGE
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   DCCURRENTDENSITY %s", type);
      lefwLines++;
      lefwTableLen = 5;
      if (value)
        encPrint(lefwFile, (char *)" %.11g ;\n", value);
      // that's it for accurrentdensity
      else {
        encPrint(lefwFile, (char *)"\n");
        // expect to have frequency & tableentries
        lefwOldState = lefwState;  // save the previous state
        lefwState    = LEFW_LAYERDCCURRENT;
      }
    } else {
      fprintf(lefwFile, "   DCCURRENTDENSITY %s", type);
      lefwLines++;
      lefwTableLen = 5;
      if (value)
        fprintf(lefwFile, " %.11g ;\n", value);  // that's it for accurrentdensity
      else {
        fprintf(lefwFile, "\n");   // expect to have frequency & tableentries
        lefwOldState = lefwState;  // save the previous state
        lefwState    = LEFW_LAYERDCCURRENT;
      }
    }
    return LEFW_OK;
  }
  
  int lefwLayerDCWidth(int numWidths, double *widths) {
    int i;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERDCCURRENT)
      return LEFW_BAD_ORDER;
  
    // width is allowed in Layer routing only
    if (lefwOldState != LEFW_LAYER_START && lefwOldState != LEFW_LAYER && lefwOldState != LEFW_LAYERROUTING_START
        && lefwOldState != LEFW_LAYERROUTING)
      return LEFW_BAD_DATA;
  
    if (numWidths <= 0)
      return LEFW_BAD_DATA;  // width is required
  
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      WIDTH ");
      for (i = 0; i < numWidths; i++) {
        encPrint(lefwFile, (char *)"%.11g ", *widths++);
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      WIDTH ");
      for (i = 0; i < numWidths; i++) {
        fprintf(lefwFile, "%.11g ", *widths++);
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwTableLen = numWidths;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerDCCutarea(int numCutareas, double *cutareas) {
    int i;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERDCCURRENT)
      return LEFW_BAD_ORDER;
  
    // cutarea is allowed in Layer non-routing only
    if (lefwOldState != LEFW_LAYER_START && lefwOldState != LEFW_LAYER && lefwOldState != LEFW_LAYERROUTING_START
        && lefwOldState != LEFW_LAYERROUTING)
      return LEFW_BAD_DATA;
  
    if (numCutareas <= 0)
      return LEFW_BAD_DATA;  // cutarea is required
  
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      CUTAREA ");
      for (i = 0; i < numCutareas; i++) {
        encPrint(lefwFile, (char *)"%.11g ", *cutareas++);
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      CUTAREA ");
      for (i = 0; i < numCutareas; i++) {
        fprintf(lefwFile, "%.11g ", *cutareas++);
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwTableLen = numCutareas;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerDCTableEntries(int numEntries, double *entries) {
    int i;
    int j = 0;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERDCCURRENT)
      return LEFW_BAD_ORDER;
  
    if (numEntries <= 0)
      return LEFW_BAD_DATA;  // tableEntries are required
  
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      TABLEENTRIES\n        ");
      for (i = 0; i < numEntries; i++) {
        if (++j > lefwTableLen) {
          encPrint(lefwFile, (char *)"\n        ");
          j = 1;
        }
        encPrint(lefwFile, (char *)"%.11g ", *entries++);
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      TABLEENTRIES\n        ");
      for (i = 0; i < numEntries; i++) {
        if (++j > lefwTableLen) {
          fprintf(lefwFile, "\n        ");
          j = 1;
        }
        fprintf(lefwFile, "%.11g ", *entries++);
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwState = lefwOldState;  // restore the previous state
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerAntennaModel(const char *oxide) {
    lefw54Num = LEFW_ANTENNAMODEL;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING && lefwState != LEFW_LAYER_START
        && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    // only routing or cut calls this func
    if (!lefwIsRouting && !lefwIsCut)
      return LEFW_BAD_DATA;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ANTENNAMODEL %s ;\n", oxide);
    else
      fprintf(lefwFile, "   ANTENNAMODEL %s ;\n", oxide);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerAntennaAreaRatio(double value) {
    lefw54Num = LEFW_ANTENNAAREARATIO;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING && lefwState != LEFW_LAYER_START
        && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    // only routing or cut calls this func
    if (!lefwIsRouting && !lefwIsCut)
      return LEFW_BAD_DATA;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ANTENNAAREARATIO %.11g ;\n", value);
    else
      fprintf(lefwFile, "   ANTENNAAREARATIO %.11g ;\n", value);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerAntennaDiffAreaRatio(double value) {
    lefw54Num = LEFW_ANTENNADIFFAREARATIO;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING && lefwState != LEFW_LAYER_START
        && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    // only routing or cut calls this func
    if (!lefwIsRouting && !lefwIsCut)
      return LEFW_BAD_DATA;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ANTENNADIFFAREARATIO %.11g ;\n", value);
    else
      fprintf(lefwFile, "   ANTENNADIFFAREARATIO %.11g ;\n", value);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerAntennaDiffAreaRatioPwl(int numPwls, double *diffusions, double *ratios) {
    int i;
  
    lefw54Num = LEFW_ANTENNADIFFAREARATIOPWL;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING && lefwState != LEFW_LAYER_START
        && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    // only routing or cut calls this func
    if (!lefwIsRouting && !lefwIsCut)
      return LEFW_BAD_DATA;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   ANTENNADIFFAREARATIO PWL ( ");
      for (i = 0; i < numPwls; i++) encPrint(lefwFile, (char *)"( %.11g %.11g ) ", *diffusions++, *ratios++);
      encPrint(lefwFile, (char *)") ;\n");
    } else {
      fprintf(lefwFile, "   ANTENNADIFFAREARATIO PWL ( ");
      for (i = 0; i < numPwls; i++) fprintf(lefwFile, "( %.11g %.11g ) ", *diffusions++, *ratios++);
      fprintf(lefwFile, ") ;\n");
    }
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerAntennaCumAreaRatio(double value) {
    lefw54Num = LEFW_ANTENNACUMAREARATIO;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING && lefwState != LEFW_LAYER_START
        && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    // only routing or cut calls this func
    if (!lefwIsRouting && !lefwIsCut)
      return LEFW_BAD_DATA;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ANTENNACUMAREARATIO %.11g ;\n", value);
    else
      fprintf(lefwFile, "   ANTENNACUMAREARATIO %.11g ;\n", value);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerAntennaCumDiffAreaRatio(double value) {
    lefw54Num = LEFW_ANTENNACUMDIFFAREARATIO;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING && lefwState != LEFW_LAYER_START
        && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    // only routing or cut calls this func
    if (!lefwIsRouting && !lefwIsCut)
      return LEFW_BAD_DATA;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ANTENNACUMDIFFAREARATIO %.11g ;\n", value);
    else
      fprintf(lefwFile, "   ANTENNACUMDIFFAREARATIO %.11g ;\n", value);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerAntennaCumDiffAreaRatioPwl(int numPwls, double *diffusions, double *ratios) {
    int i;
  
    lefw54Num = LEFW_ANTENNACUMDIFFAREARATIOPWL;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING && lefwState != LEFW_LAYER_START
        && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    // only routing or cut calls this func
    if (!lefwIsRouting && !lefwIsCut)
      return LEFW_BAD_DATA;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   ANTENNACUMDIFFAREARATIO PWL ( ");
      for (i = 0; i < numPwls; i++) encPrint(lefwFile, (char *)"( %.11g %.11g ) ", *diffusions++, *ratios++);
      encPrint(lefwFile, (char *)") ;\n");
    } else {
      fprintf(lefwFile, "   ANTENNACUMDIFFAREARATIO PWL ( ");
      for (i = 0; i < numPwls; i++) fprintf(lefwFile, "( %.11g %.11g ) ", *diffusions++, *ratios++);
      fprintf(lefwFile, ") ;\n");
    }
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerAntennaAreaFactor(double value, const char *diffUseOnly) {
    lefw54Num = LEFW_ANTENNAAREAFACTOR;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING && lefwState != LEFW_LAYER_START
        && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    // only routing or cut calls this func
    if (!lefwIsRouting && !lefwIsCut)
      return LEFW_BAD_DATA;
    if ((versionNum < 5.4) && (diffUseOnly && strcmp(diffUseOnly, "DIFFUSEONLY") == 0))
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   ANTENNAAREAFACTOR %.11g ", value);
      if (diffUseOnly && strcmp(diffUseOnly, "DIFFUSEONLY") == 0)
        encPrint(lefwFile, (char *)"   DIFFUSEONLY ");
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "   ANTENNAAREAFACTOR %.11g ", value);
      if (diffUseOnly && strcmp(diffUseOnly, "DIFFUSEONLY") == 0)
        fprintf(lefwFile, "DIFFUSEONLY ");
      fprintf(lefwFile, ";\n");
    }
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerAntennaSideAreaRatio(double value) {
    lefw54Num = LEFW_ANTENNASIDEAREARATIO;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    // only routing calls this func
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ANTENNASIDEAREARATIO %.11g ;\n", value);
    else
      fprintf(lefwFile, "   ANTENNASIDEAREARATIO %.11g ;\n", value);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerAntennaDiffSideAreaRatio(double value) {
    lefw54Num = LEFW_ANTENNADIFFSIDEAREARATIO;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    // only routing calls this func
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ANTENNADIFFSIDEAREARATIO %.11g ;\n", value);
    else
      fprintf(lefwFile, "   ANTENNADIFFSIDEAREARATIO %.11g ;\n", value);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerAntennaDiffSideAreaRatioPwl(int numPwls, double *diffusions, double *ratios) {
    int i;
  
    lefw54Num = LEFW_ANTENNADIFFSIDEAREARATIOPWL;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    // only routing or cut calls this func
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   ANTENNADIFFSIDEAREARATIO PWL ( ");
      for (i = 0; i < numPwls; i++) encPrint(lefwFile, (char *)"( %.11g %.11g ) ", *diffusions++, *ratios++);
      encPrint(lefwFile, (char *)") ;\n");
    } else {
      fprintf(lefwFile, "   ANTENNADIFFSIDEAREARATIO PWL ( ");
      for (i = 0; i < numPwls; i++) fprintf(lefwFile, "( %.11g %.11g ) ", *diffusions++, *ratios++);
      fprintf(lefwFile, ") ;\n");
    }
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerAntennaCumSideAreaRatio(double value) {
    lefw54Num = LEFW_ANTENNACUMSIDEAREARATIO;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    // only routing calls this func
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ANTENNACUMSIDEAREARATIO %.11g ;\n", value);
    else
      fprintf(lefwFile, "   ANTENNACUMSIDEAREARATIO %.11g ;\n", value);
    lefwLines++;
    return LEFW_OK;
  }
  
  // 11/25/2002 - bug fix: submitted by Craig Files (cfiles@ftc.agilent.com)
  // Renamed from lefwLayerAntennaCumSideDiffAreaRatio to match
  // the header
  int lefwLayerAntennaCumDiffSideAreaRatio(double value) {
    lefw54Num = LEFW_ANTENNACUMDIFFSIDEAREARATIO;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    // only routing calls this func
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ANTENNACUMDIFFSIDEAREARATIO %.11g ;\n", value);
    else
      fprintf(lefwFile, "   ANTENNACUMDIFFSIDEAREARATIO %.11g ;\n", value);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerAntennaCumDiffSideAreaRatioPwl(int numPwls, double *diffusions, double *ratios) {
    int i;
  
    lefw54Num = LEFW_ANTENNACUMDIFFSIDEAREARATIOPWL;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    // only routing or cut calls this func
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   ANTENNACUMDIFFSIDEAREARATIO PWL ( ");
      for (i = 0; i < numPwls; i++) encPrint(lefwFile, (char *)"( %.11g %.11g ) ", *diffusions++, *ratios++);
      encPrint(lefwFile, (char *)") ;\n");
    } else {
      fprintf(lefwFile, "   ANTENNACUMDIFFSIDEAREARATIO PWL ( ");
      for (i = 0; i < numPwls; i++) fprintf(lefwFile, "( %.11g %.11g ) ", *diffusions++, *ratios++);
      fprintf(lefwFile, ") ;\n");
    }
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwLayerAntennaSideAreaFactor(double value, const char *diffUseOnly) {
    lefw54Num = LEFW_ANTENNASIDEAREAFACTOR;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING)
      return LEFW_BAD_ORDER;
    // only routing calls this func
    if (!lefwIsRouting)
      return LEFW_BAD_DATA;
    if ((versionNum < 5.4) && (diffUseOnly && strcmp(diffUseOnly, "DIFFUSEONLY") == 0))
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   ANTENNASIDEAREAFACTOR %.11g ", value);
      if (diffUseOnly && strcmp(diffUseOnly, "DIFFUSEONLY") == 0)
        encPrint(lefwFile, (char *)"   DIFFUSEONLY ");
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "   ANTENNASIDEAREAFACTOR %.11g ", value);
      if (diffUseOnly && strcmp(diffUseOnly, "DIFFUSEONLY") == 0)
        fprintf(lefwFile, "DIFFUSEONLY ");
      fprintf(lefwFile, ";\n");
    }
    lefwLines++;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerAntennaCumRoutingPlusCut() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING && lefwState != LEFW_LAYER_START
        && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting && !lefwIsCut)
      return LEFW_BAD_DATA;
    /* WANDA
      if ((versionNum < 5.4) &&
          (diffUseOnly && strcmp(diffUseOnly, "DIFFUSEONLY") == 0))
         return LEFW_WRONG_VERSION;
    */
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ANTENNACUMROUTINGPLUSCUT ;\n");
    else {
      fprintf(lefwFile, "   ANTENNACUMROUTINGPLUSCUT ;\n");
    }
    lefwLines++;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerAntennaGatePlusDiff(double plusDiffFactor) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING && lefwState != LEFW_LAYER_START
        && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting && !lefwIsCut)
      return LEFW_BAD_DATA;
    /* WANDA
      if ((versionNum < 5.4) &&
          (diffUseOnly && strcmp(diffUseOnly, "DIFFUSEONLY") == 0))
         return LEFW_WRONG_VERSION;
    */
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ANTENNAGATEPLUSDIFF %.11g ;\n", plusDiffFactor);
    else {
      fprintf(lefwFile, "   ANTENNAGATEPLUSDIFF %.11g ;\n", plusDiffFactor);
    }
    lefwLines++;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerAntennaAreaMinusDiff(double minusDiffFactor) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING && lefwState != LEFW_LAYER_START
        && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting && !lefwIsCut)
      return LEFW_BAD_DATA;
    /* WANDA
      if ((versionNum < 5.4) &&
          (diffUseOnly && strcmp(diffUseOnly, "DIFFUSEONLY") == 0))
         return LEFW_WRONG_VERSION;
    */
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ANTENNAAREAMINUSDIFF %.11g ;\n", minusDiffFactor);
    else {
      fprintf(lefwFile, "   ANTENNAAREAMINUSDIFF %.11g ;\n", minusDiffFactor);
    }
    lefwLines++;
    return LEFW_OK;
  }
  
  // 5.7
  int lefwLayerAntennaAreaDiffReducePwl(int numPwls, double *diffAreas, double *metalDiffFactors) {
    int i;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_LAYERROUTING_START && lefwState != LEFW_LAYERROUTING && lefwState != LEFW_LAYER_START
        && lefwState != LEFW_LAYER)
      return LEFW_BAD_ORDER;
    if (!lefwIsRouting && !lefwIsCut)
      return LEFW_BAD_DATA;
    /* WANDA
      if (versionNum < 5.4)
         return LEFW_WRONG_VERSION;
    */
    if (numPwls < 2)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   ANTENNAAREADIFFREDUCEPWL ( ");
      for (i = 0; i < numPwls; i++) encPrint(lefwFile, (char *)"( %.11g %.11g ) ", *diffAreas++, *metalDiffFactors++);
      encPrint(lefwFile, (char *)") ;\n");
    } else {
      fprintf(lefwFile, "   ANTENNAAREADIFFREDUCEPWL ( ");
      for (i = 0; i < numPwls; i++) fprintf(lefwFile, "( %.11g %.11g ) ", *diffAreas++, *metalDiffFactors++);
      fprintf(lefwFile, ") ;\n");
    }
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwMinimumDensity(double minDensity) {
    lefw54Num = LEFW_MINIMUMDENSITY;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   MINIMUMDENSITY %.11g ;\n", minDensity);
    else
      fprintf(lefwFile, "   MINIMUMDENSITY %.11g ;\n", minDensity);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwMaximumDensity(double maxDensity) {
    lefw54Num = LEFW_MAXIMUMDENSITY;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   MAXIMUMDENSITY %.11g ;\n", maxDensity);
    else
      fprintf(lefwFile, "   MAXIMUMDENSITY %.11g ;\n", maxDensity);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwDensityCheckWindow(double checkWindowLength, double checkWindowWidth) {
    lefw54Num = LEFW_DENSITYCHECKWINDOW;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   DENSITYCHECKWINDOW %.11g %.11g ;\n", checkWindowLength, checkWindowWidth);
    else
      fprintf(lefwFile, "   DENSITYCHECKWINDOW %.11g %.11g ;\n", checkWindowLength, checkWindowWidth);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwDensityCheckStep(double checkStepValue) {
    lefw54Num = LEFW_DENSITYCHECKSTEP;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   DENSITYCHECKSTEP %.11g ;\n", checkStepValue);
    else
      fprintf(lefwFile, "   DENSITYCHECKSTEP %.11g ;\n", checkStepValue);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwFillActiveSpacing(double fillToActiveSpacing) {
    lefw54Num = LEFW_FILLACTIVESPACING;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   FILLACTIVESPACING %.11g ;\n", fillToActiveSpacing);
    else
      fprintf(lefwFile, "   FILLACTIVESPACING %.11g ;\n", fillToActiveSpacing);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwMaxviastack(int value, const char *bottomLayer, const char *topLayer) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwIsMaxviastack)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"MAXVIASTACK %d ", value);
      if (bottomLayer)
        encPrint(lefwFile, (char *)"RANGE %s %s ;\n", bottomLayer, topLayer);
      else
        encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "MAXVIASTACK %d ", value);
      if (bottomLayer)
        fprintf(lefwFile, "RANGE %s %s ;\n", bottomLayer, topLayer);
      else
        fprintf(lefwFile, ";\n");
    }
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwStartPropDef() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwSynArray[LEFW_PROPERTYDEF_START])
      return LEFW_ALREADY_DEFINED;
    lefwSynArray[LEFW_ANTENNASIZE] = 1;
    if (lefwState == LEFW_PROPERTYDEF_START || lefwState == LEFW_PROPERTYDEF)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"PROPERTYDEFINITIONS\n");
    else
      fprintf(lefwFile, "PROPERTYDEFINITIONS\n");
  
    lefwLines++;
    lefwState                            = LEFW_PROPERTYDEF_START;
    lefwSynArray[LEFW_PROPERTYDEF_START] = 1;
    return LEFW_OK;
  }
  
  int lefwIntPropDef(const char *objType, const char *propName, double leftRange,
                     double rightRange,  // optional
                     int    propValue    // optional
  ) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_PROPERTYDEF_START && lefwState != LEFW_PROPERTYDEF)
      return LEFW_BAD_ORDER;
    /*
      if ((! objType && ! *objType) || (! propName && ! *propName))
    */
    if (((objType == 0) || (*objType == 0)) || ((propName == 0) || (*propName == 0)))
      return LEFW_BAD_DATA;
  
    if (strcmp(objType, "LIBRARY") && strcmp(objType, "VIA") && strcmp(objType, "MACRO") && strcmp(objType, "PIN")
        && strcmp(objType, "LAYER") && strcmp(objType, "NONDEFAULTRULE") && strcmp(objType, "VIARULE"))
      return LEFW_BAD_DATA;
  
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   %s %s INTEGER ", objType, propName);
      if (leftRange || rightRange)
        encPrint(lefwFile, (char *)"RANGE %.11g %.11g ", leftRange, rightRange);
  
      if (propValue)
        encPrint(lefwFile, (char *)"%d ", propValue);
  
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "   %s %s INTEGER ", objType, propName);
      if (leftRange || rightRange)
        fprintf(lefwFile, "RANGE %.11g %.11g ", leftRange, rightRange);
  
      if (propValue)
        fprintf(lefwFile, "%d ", propValue);
  
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState = LEFW_PROPERTYDEF;
    return LEFW_OK;
  }
  
  int lefwRealPropDef(const char *objType, const char *propName, double leftRange,
                      double rightRange,  // optional
                      double propValue    // optional
  ) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_PROPERTYDEF_START && lefwState != LEFW_PROPERTYDEF)
      return LEFW_BAD_ORDER;
    if (((objType == 0) || (*objType == 0)) || ((propName == 0) || (*propName == 0)))  // require
      return LEFW_BAD_DATA;
  
    if (strcmp(objType, "LIBRARY") && strcmp(objType, "VIA") && strcmp(objType, "MACRO") && strcmp(objType, "PIN")
        && strcmp(objType, "LAYER") && strcmp(objType, "NONDEFAULTRULE") && strcmp(objType, "VIARULE"))
      return LEFW_BAD_DATA;
  
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   %s %s REAL ", objType, propName);
      if (leftRange || rightRange)
        encPrint(lefwFile, (char *)"RANGE %.11g %.11g ", leftRange, rightRange);
  
      if (propValue)
        encPrint(lefwFile, (char *)"%.11g ", propValue);
  
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "   %s %s REAL ", objType, propName);
      if (leftRange || rightRange)
        fprintf(lefwFile, "RANGE %.11g %.11g ", leftRange, rightRange);
  
      if (propValue)
        fprintf(lefwFile, "%.11g ", propValue);
  
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState = LEFW_PROPERTYDEF;
    return LEFW_OK;
  }
  
  int lefwStringPropDef(const char *objType, const char *propName, double leftRange,
                        double      rightRange,  // optional
                        const char *propValue    // optional
  ) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_PROPERTYDEF_START && lefwState != LEFW_PROPERTYDEF)
      return LEFW_BAD_ORDER;
    if (((objType == 0) || (*objType == 0)) || ((propName == 0) || (*propName == 0)))
      return LEFW_BAD_DATA;
  
    if (strcmp(objType, "LIBRARY") && strcmp(objType, "VIA") && strcmp(objType, "MACRO") && strcmp(objType, "PIN")
        && strcmp(objType, "LAYER") && strcmp(objType, "NONDEFAULTRULE") && strcmp(objType, "VIARULE"))
      return LEFW_BAD_DATA;
  
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   %s %s STRING ", objType, propName);
      if (leftRange || rightRange)
        encPrint(lefwFile, (char *)"RANGE %.11g %.11g ", leftRange, rightRange);
  
      if (propValue)
        encPrint(lefwFile, (char *)"\"%s\" ", propValue);  // string, set quotes
  
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "   %s %s STRING ", objType, propName);
      if (leftRange || rightRange)
        fprintf(lefwFile, "RANGE %.11g %.11g ", leftRange, rightRange);
  
      if (propValue)
        fprintf(lefwFile, "\"%s\" ", propValue);  // string, set quotes
  
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState = LEFW_PROPERTYDEF;
    return LEFW_OK;
  }
  
  int lefwEndPropDef() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_PROPERTYDEF_START && lefwState != LEFW_PROPERTYDEF)
      return LEFW_BAD_ORDER;
  
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"END PROPERTYDEFINITIONS\n\n");
    else
      fprintf(lefwFile, "END PROPERTYDEFINITIONS\n\n");
    lefwLines++;
    lefwState = LEFW_PROPERTYDEF_END;
    return LEFW_OK;
  }
  
  int lefwEnd() {
    if (!lefwFile)
      return 1;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"END LIBRARY\n");
    else
      fprintf(lefwFile, "END LIBRARY\n");
    lefwLines++;
    // lefwFile = 0;
    lefwState = LEFW_DONE;
    return LEFW_OK;
  }
  
  int lefwStartVia(const char *viaName,
                   const char *isDefault) {  // optional
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState == LEFW_VIA_START || lefwState == LEFW_VIA)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END && (!lefwIsNonDefaultRule))  // via defined in nondefaultrule
      return LEFW_BAD_ORDER;                                                        // not of the ENDs
  
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"VIA %s ", viaName);
      if (isDefault && strcmp(isDefault, "DEFAULT") == 0)
        encPrint(lefwFile, (char *)"DEFAULT");
      encPrint(lefwFile, (char *)"\n");
    } else {
      fprintf(lefwFile, "VIA %s ", viaName);
      if (isDefault && strcmp(isDefault, "DEFAULT") == 0)
        fprintf(lefwFile, "DEFAULT");
      fprintf(lefwFile, "\n");
    }
    lefwLines++;
  
    lefwSynArray[LEFW_VIA_START] = 1;
    lefwState                    = LEFW_VIA_START;
    lefwDidLayer                 = 0;  // hasn't set the layer yet
    lefwViaHasVal                = 0;
    return LEFW_OK;
  }
  
  int lefwViaTopofstackonly() {
    lefwObsoleteNum = LEFW_VIATOPOFSTACKONLY;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_VIA_START && lefwState != LEFW_VIA)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.6)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   TOPOFSTACKONLY\n");
    else
      fprintf(lefwFile, "   TOPOFSTACKONLY\n");
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwViaForeign(const char *foreignName,
                     double      xl,  // optional
                     double      yl,  // optional
                     int         orient) {    // optional
    lefwObsoleteNum = LEFW_VIAFOREIGN;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_VIA_START && lefwState != LEFW_VIA)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.6)
      return LEFW_OBSOLETE;
  
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   FOREIGN %s ", foreignName);
      if (xl || yl) {
        encPrint(lefwFile, (char *)"%.11g %.11g ", xl, yl);
        if (orient >= 0 && orient <= 7)
          encPrint(lefwFile, (char *)"%s ", lefwOrient(orient));
      } else if (orient > 0 && orient <= 7) {  // assume user has 0 0 for pt
        encPrint(lefwFile, (char *)"%.11g %.11g ", xl, yl);
        encPrint(lefwFile, (char *)"%s ", lefwOrient(orient));
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "   FOREIGN %s ", foreignName);
      if (xl || yl) {
        fprintf(lefwFile, "%.11g %.11g ", xl, yl);
        if (orient >= 0 && orient <= 7)
          fprintf(lefwFile, "%s ", lefwOrient(orient));
      } else if (orient > 0 && orient <= 7) {  // assume user has 0 0 for pt
        fprintf(lefwFile, "%.11g %.11g ", xl, yl);
        fprintf(lefwFile, "%s ", lefwOrient(orient));
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState = LEFW_VIA;
    return LEFW_OK;
  }
  
  int lefwViaForeignStr(const char *foreignName,
                        double      xl,        // optional
                        double      yl,        // optional
                        const char *orient) {  // optional
    lefwObsoleteNum = LEFW_VIAFOREIGN;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_VIA_START && lefwState != LEFW_VIA)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.6)
      return LEFW_OBSOLETE;
  
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   FOREIGN %s ", foreignName);
      if (xl || yl) {
        encPrint(lefwFile, (char *)"%.11g %.11g ", xl, yl);
        if (orient && *orient != '\0')
          encPrint(lefwFile, (char *)"%s ", orient);
      } else if (orient && *orient != '\0') {  // assume user has 0 0 for pt
        encPrint(lefwFile, (char *)"%.11g %.11g ", xl, yl);
        encPrint(lefwFile, (char *)"%s ", orient);
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "   FOREIGN %s ", foreignName);
      if (xl || yl) {
        fprintf(lefwFile, "%.11g %.11g ", xl, yl);
        if (orient && *orient != '\0')
          fprintf(lefwFile, "%s ", orient);
      } else if (orient && *orient != '\0') {  // assume user has 0 0 for pt
        fprintf(lefwFile, "%.11g %.11g ", xl, yl);
        fprintf(lefwFile, "%s ", orient);
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState = LEFW_VIA;
    return LEFW_OK;
  }
  
  int lefwViaResistance(double resistance) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_VIA_START && lefwState != LEFW_VIA)
      return LEFW_BAD_ORDER;
  
    if (lefwViaHasVal)
      return LEFW_ALREADY_DEFINED;  // either Resistance or
    // ViaRule has defined
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   RESISTANCE %.11g ;\n", resistance);
    else
      fprintf(lefwFile, "   RESISTANCE %.11g ;\n", resistance);
  
    lefwLines++;
    lefwState     = LEFW_VIA;
    lefwViaHasVal = 1;
    return LEFW_OK;
  }
  
  int lefwViaLayer(const char *layerName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_VIA_START && lefwState != LEFW_VIA)
      return LEFW_BAD_ORDER;
  
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   LAYER %s ;\n", layerName);
    else
      fprintf(lefwFile, "   LAYER %s ;\n", layerName);
  
    lefwLines++;
    lefwState    = LEFW_VIA;
    lefwDidLayer = 1;
    return LEFW_OK;
  }
  
  int lefwViaLayerRect(double x1l, double y1l, double x2l, double y2l, int mask) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_VIA_START && lefwState != LEFW_VIA)
      return LEFW_BAD_ORDER;
    if (!lefwDidLayer)
      return LEFW_BAD_ORDER;
  
    if (mask && versionNum < 5.8) {
      return LEFW_WRONG_VERSION;
    }
  
    if (!lefwValidateMaskNumber(mask)) {
      return LEFW_BAD_DATA;
    }
  
    if (lefwWriteEncrypt) {
      if (mask) {
        encPrint(lefwFile, (char *)"      RECT MASK %d %.11g %.11g %.11g %.11g ;\n", mask, x1l, y1l, x2l, y2l);
      } else {
        encPrint(lefwFile, (char *)"      RECT %.11g %.11g %.11g %.11g ;\n", x1l, y1l, x2l, y2l);
      }
    } else {
      if (mask) {
        fprintf(lefwFile, "      RECT MASK %d %.11g %.11g %.11g %.11g ;\n", mask, x1l, y1l, x2l, y2l);
      } else {
        fprintf(lefwFile, "      RECT %.11g %.11g %.11g %.11g ;\n", x1l, y1l, x2l, y2l);
      }
    }
  
    lefwLines++;
    lefwState = LEFW_VIA;
    return LEFW_OK;
  }
  
  int lefwViaLayerPolygon(int num_polys, double *xl, double *yl, int mask) {
    int i;
    int polyCount;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_VIA_START && lefwState != LEFW_VIA)
      return LEFW_BAD_ORDER;
    if (!lefwDidLayer)
      return LEFW_BAD_ORDER;
    if (num_polys < 4)
      return LEFW_BAD_DATA;
  
    if (mask && versionNum < 5.8) {
      return LEFW_WRONG_VERSION;
    }
  
    if (!lefwValidateMaskNumber(mask)) {
      return LEFW_BAD_DATA;
    }
  
    if (lefwWriteEncrypt) {
      if (mask) {
        encPrint(lefwFile, (char *)"      POLYGON MASK %d ", mask);
      } else {
        encPrint(lefwFile, (char *)"      POLYGON ");
      }
      polyCount = 0;
      for (i = 0; i < num_polys; i++) {
        if (i == 0)
          encPrint(lefwFile, (char *)"%.11g %.11g ", *xl++, *yl++);
        else {
          if ((i % 5) == 0) {
            encPrint(lefwFile, (char *)"\n              %.11g %.11g", *xl++, *yl++);
            lefwLines++;
          } else
            encPrint(lefwFile, (char *)"%.11g %.11g ", *xl++, *yl++);
        }
      }
      encPrint(lefwFile, (char *)" ;\n");
    } else {
      if (mask) {
        fprintf(lefwFile, "      POLYGON MASK %d ", mask);
      } else {
        fprintf(lefwFile, "      POLYGON ");
      }
      polyCount = 0;
      for (i = 0; i < num_polys; i++) {
        if (i == 0)
          fprintf(lefwFile, "%.11g %.11g", *xl++, *yl++);
        else {
          if ((i % 5) == 0) {
            fprintf(lefwFile, "\n              %.11g %.11g", *xl++, *yl++);
            lefwLines++;
          } else
            fprintf(lefwFile, "%.11g %.11g ", *xl++, *yl++);
        }
      }
      fprintf(lefwFile, " ;\n");
    }
    lefwLines++;
    lefwState = LEFW_VIA;
    return LEFW_OK;
  }
  
  int lefwViaViarule(const char *viaRuleName, double xCutSize, double yCutSize, const char *botMetalLayer, const char *cutLayer,
                     const char *topMetalLayer, double xCutSpacing, double yCutSpacing, double xBotEnc, double yBotEnc,
                     double xTopEnc, double yTopEnc) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_VIA_START && lefwState != LEFW_VIA)
      return LEFW_BAD_ORDER;
  
    if (lefwViaHasVal)
      return LEFW_ALREADY_DEFINED;  // either Resistance or
    // ViaRule has defined
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   VIARULE %s ;\n", viaRuleName);
      encPrint(lefwFile, (char *)"     CUTSIZE %.11g %.11g ;\n", xCutSize, yCutSize);
      encPrint(lefwFile, (char *)"     LAYERS %s %s %s ;\n", botMetalLayer, cutLayer, topMetalLayer);
      encPrint(lefwFile, (char *)"     CUTSPACING %.11g %.11g ;\n", xCutSpacing, yCutSpacing);
      encPrint(lefwFile, (char *)"     ENCLOSURE %.11g %.11g %.11g %.11g ;\n", xBotEnc, yBotEnc, xTopEnc, yTopEnc);
    } else {
      fprintf(lefwFile, "   VIARULE %s ;\n", viaRuleName);
      fprintf(lefwFile, "     CUTSIZE %.11g %.11g ;\n", xCutSize, yCutSize);
      fprintf(lefwFile, "     LAYERS %s %s %s ;\n", botMetalLayer, cutLayer, topMetalLayer);
      fprintf(lefwFile, "     CUTSPACING %.11g %.11g ;\n", xCutSpacing, yCutSpacing);
      fprintf(lefwFile, "     ENCLOSURE %.11g %.11g %.11g %.11g ;\n", xBotEnc, yBotEnc, xTopEnc, yTopEnc);
    }
    lefwLines++;
    lefwState     = LEFW_VIAVIARULE;
    lefwViaHasVal = 1;
    return LEFW_OK;
  }
  
  int lefwViaViaruleRowCol(int numCutRows, int numCutCols) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_VIAVIARULE)
      return LEFW_BAD_ORDER;
  
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"     ROWCOL %d %d ;\n", numCutRows, numCutCols);
    else
      fprintf(lefwFile, "     ROWCOL %d %d ;\n", numCutRows, numCutCols);
  
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwViaViaruleOrigin(double xOffset, double yOffset) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_VIAVIARULE)
      return LEFW_BAD_ORDER;
  
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"     ORIGIN %.11g %.11g ;\n", xOffset, yOffset);
    else
      fprintf(lefwFile, "     ORIGIN %.11g %.11g ;\n", xOffset, yOffset);
  
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwViaViaruleOffset(double xBotOffset, double yBotOffset, double xTopOffset, double yTopOffset) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_VIAVIARULE)
      return LEFW_BAD_ORDER;
  
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"     OFFSET %.11g %.11g %.11g %.11g ;\n", xBotOffset, yBotOffset, xTopOffset, yTopOffset);
    else
      fprintf(lefwFile, "     OFFSET %.11g %.11g %.11g %.11g ;\n", xBotOffset, yBotOffset, xTopOffset, yTopOffset);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwViaViarulePattern(const char *cutPattern) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_VIAVIARULE)
      return LEFW_BAD_ORDER;
  
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"     PATTERN %s ;\n", cutPattern);
    else
      fprintf(lefwFile, "     PATTERN %s ;\n", cutPattern);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwStringProperty(const char *propName, const char *propValue) {
    if ((lefwState != LEFW_VIA) && (lefwState != LEFW_LAYER) && (lefwState != LEFW_VIARULE) && (lefwState != LEFW_MACRO_START)
        && (lefwState != LEFW_MACRO) && (lefwState != LEFW_VIA_START) && (lefwState != LEFW_VIARULE_START)
        && (lefwState != LEFW_LAYER_START) && (lefwState != LEFW_BEGINEXT) && (lefwState != LEFW_VIAVIARULE)
        && (lefwState != LEFW_LAYERROUTING_START) && (lefwState != LEFW_LAYERROUTING))
      return LEFW_BAD_ORDER;
  
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   PROPERTY %s \"%s\" ;\n", propName, propValue);
    else
      fprintf(lefwFile, "   PROPERTY %s \"%s\" ;\n", propName, propValue);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwRealProperty(const char *propName, double propValue) {
    if ((lefwState != LEFW_VIA) && (lefwState != LEFW_LAYER) && (lefwState != LEFW_VIARULE) && (lefwState != LEFW_MACRO_START)
        && (lefwState != LEFW_MACRO) && (lefwState != LEFW_VIA_START) && (lefwState != LEFW_VIARULE_START)
        && (lefwState != LEFW_LAYER_START) && (lefwState != LEFW_BEGINEXT) && (lefwState != LEFW_VIAVIARULE))
      return LEFW_BAD_ORDER;
  
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   PROPERTY %s %.11g ;\n", propName, propValue);
    else
      fprintf(lefwFile, "   PROPERTY %s %.11g ;\n", propName, propValue);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwIntProperty(const char *propName, int propValue) {
    if ((lefwState != LEFW_VIA) && (lefwState != LEFW_LAYER) && (lefwState != LEFW_VIARULE) && (lefwState != LEFW_MACRO_START)
        && (lefwState != LEFW_MACRO) && (lefwState != LEFW_VIA_START) && (lefwState != LEFW_VIARULE_START)
        && (lefwState != LEFW_LAYER_START) && (lefwState != LEFW_BEGINEXT) && (lefwState != LEFW_VIAVIARULE))
      return LEFW_BAD_ORDER;
  
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   PROPERTY %s %d ;\n", propName, propValue);
    else
      fprintf(lefwFile, "   PROPERTY %s %d ;\n", propName, propValue);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwEndVia(const char *viaName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_VIA_START && lefwState != LEFW_VIA && lefwState != LEFW_VIAVIARULE)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"END %s\n\n", viaName);
    else
      fprintf(lefwFile, "END %s\n\n", viaName);
  
    lefwLines++;
    lefwState    = LEFW_VIA_END;
    lefwDidLayer = 0;
    return LEFW_OK;
  }
  
  // internal function
  int lefwViaRulePrtLayer(const char *layerName, const char *direction, double minWidth, double maxWidth, double overhang,
                          double metalOverhang) {
    lefwObsoleteNum = LEFW_VIARULEGENERATE;
    if (!layerName || layerName == 0 || *layerName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   LAYER %s ;\n", layerName);
    else
      fprintf(lefwFile, "   LAYER %s ;\n", layerName);
    if (direction && strcmp(direction, "HORIZONTAL") && strcmp(direction, "VERTICAL"))
      return LEFW_BAD_DATA;
    if (versionNum >= 5.6 && (direction || overhang || metalOverhang))
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt) {
      if (direction) {
        encPrint(lefwFile, (char *)"      DIRECTION %s ;\n", direction);
        lefwLines = lefwLines + 2;
      } else
        lefwLines++;
      if (minWidth || maxWidth) {
        encPrint(lefwFile, (char *)"      WIDTH %.11g TO %.11g ;\n", minWidth, maxWidth);
        lefwLines++;
      }
      if (overhang) {
        encPrint(lefwFile, (char *)"      OVERHANG %.11g ;\n", overhang);
        lefwLines++;
      }
      if (metalOverhang) {
        encPrint(lefwFile, (char *)"      METALOVERHANG %.11g ;\n", metalOverhang);
        lefwLines++;
      }
    } else {
      if (direction) {
        fprintf(lefwFile, "      DIRECTION %s ;\n", direction);
        lefwLines = lefwLines + 2;
      } else
        lefwLines++;
      if (minWidth || maxWidth) {
        fprintf(lefwFile, "      WIDTH %.11g TO %.11g ;\n", minWidth, maxWidth);
        lefwLines++;
      }
      if (overhang) {
        fprintf(lefwFile, "      OVERHANG %.11g ;\n", overhang);
        lefwLines++;
      }
      if (metalOverhang) {
        fprintf(lefwFile, "      METALOVERHANG %.11g ;\n", metalOverhang);
        lefwLines++;
      }
    }
    return LEFW_OK;
  }
  
  int lefwStartViaRule(const char *viaRuleName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState == LEFW_VIARULE_START || lefwState == LEFW_VIARULE)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
  
    if (!viaRuleName || viaRuleName == 0 || *viaRuleName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"VIARULE %s\n", viaRuleName);
    else
      fprintf(lefwFile, "VIARULE %s\n", viaRuleName);
    lefwLines++;
  
    lefwSynArray[LEFW_VIARULE_START] = 1;
    lefwState                        = LEFW_VIARULE_START;
    lefwDidLayer                     = 0;  // hasn't set the layer yet
    lefwNumViaRuleLayers             = 0;
    return LEFW_OK;
  }
  
  int lefwViaRuleLayer(const char *layerName, const char *direction, double minWidth,
                       double maxWidth,  // optional
                       double overhang,
                       double metalOverhang) {  // optional
    int status;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_VIARULE_START && lefwState != LEFW_VIARULE)
      return LEFW_BAD_ORDER;
    if (lefwNumViaRuleLayers >= 2)
      return LEFW_BAD_ORDER;
    if ((status = lefwViaRulePrtLayer(layerName, direction, minWidth, maxWidth, overhang, metalOverhang)) != LEFW_OK)
      return status;
    lefwNumViaRuleLayers++;
    lefwState = LEFW_VIARULE;
    return LEFW_OK;
  }
  
  int lefwViaRuleVia(const char *viaName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_VIARULE)
      return LEFW_BAD_ORDER;
    if (lefwNumViaRuleLayers != 2)  // this routine has to be after two layers
      return LEFW_BAD_ORDER;        // be written
    if (!viaName || !*viaName)      // viaName is required
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      VIA %s ;\n", viaName);
    else
      fprintf(lefwFile, "      VIA %s ;\n", viaName);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwEndViaRule(const char *viaRuleName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_VIARULE_START && lefwState != LEFW_VIARULE)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"END %s\n\n", viaRuleName);
    else
      fprintf(lefwFile, "END %s\n\n", viaRuleName);
  
    lefwLines++;
    lefwState            = LEFW_VIARULE_END;
    lefwDidLayer         = 0;
    lefwNumViaRuleLayers = 0;
    return LEFW_OK;
  }
  
  int lefwStartViaRuleGen(const char *viaRuleName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState == LEFW_VIARULEGEN_START || lefwState == LEFW_VIARULEGEN)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
  
    if (!viaRuleName || viaRuleName == 0 || *viaRuleName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"VIARULE %s GENERATE", viaRuleName);
    else
      fprintf(lefwFile, "VIARULE %s GENERATE", viaRuleName);
    lefwLines++;
  
    lefwSynArray[LEFW_VIARULEGEN_START] = 1;
    lefwState                           = LEFW_VIARULEGEN_START;
    lefwDidLayer                        = 0;  // hasn't set the layer yet
    lefwNumViaRuleLayers                = 0;
    return LEFW_OK;
  }
  
  int lefwViaRuleGenDefault() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_VIARULEGEN_START && lefwState != LEFW_VIARULEGEN)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)" DEFAULT");
    else
      fprintf(lefwFile, " DEFAULT");
    return LEFW_OK;
  }
  
  int lefwViaRuleGenLayer(const char *layerName, const char *direction, double minWidth,
                          double maxWidth,  // optional
                          double overhang,
                          double metalOverhang) {  // optional
    int status;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_VIARULEGEN_START && lefwState != LEFW_VIARULEGEN)
      return LEFW_BAD_ORDER;
    if (lefwNumViaRuleLayers >= 2)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)                // add a new line since, lefwViaRuleGen
      encPrint(lefwFile, (char *)"\n");  // & lefwViaRuleGenDefault do not
    else
      fprintf(lefwFile, "\n");
    if ((status = lefwViaRulePrtLayer(layerName, direction, minWidth, maxWidth, overhang, metalOverhang)) != LEFW_OK)
      return status;
    lefwNumViaRuleLayers++;
    lefwState = LEFW_VIARULEGEN;
    return LEFW_OK;
  }
  
  int lefwViaRuleGenLayerEnclosure(const char *layerName, double overhang1, double overhang2, double minWidth,
                                   double maxWidth) {  // optional
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_VIARULEGEN_START && lefwState != LEFW_VIARULEGEN)
      return LEFW_BAD_ORDER;
    if (lefwNumViaRuleLayers >= 2)
      return LEFW_BAD_ORDER;
  
    if (!layerName || layerName == 0 || *layerName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"\n   LAYER %s ;\n", layerName);
    else
      fprintf(lefwFile, "\n   LAYER %s ;\n", layerName);
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      ENCLOSURE %.11g %.11g ;\n", overhang1, overhang2);
      lefwLines = lefwLines + 2;
      if (minWidth || maxWidth) {
        encPrint(lefwFile, (char *)"      WIDTH %.11g TO %.11g ;\n", minWidth, maxWidth);
        lefwLines++;
      }
    } else {
      fprintf(lefwFile, "      ENCLOSURE %.11g %.11g ;\n", overhang1, overhang2);
      lefwLines = lefwLines + 2;
      if (minWidth || maxWidth) {
        fprintf(lefwFile, "      WIDTH %.11g TO %.11g ;\n", minWidth, maxWidth);
        lefwLines++;
      }
    }
  
    lefwNumViaRuleLayers++;
    lefwState = LEFW_VIARULEGEN;
    return LEFW_OK;
  }
  
  int lefwViaRuleGenLayer3(const char *layerName, double xl, double yl, double xh, double yh, double xSpacing, double ySpacing,
                           double resistance) {  // optional
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_VIARULEGEN)
      return LEFW_BAD_ORDER;
    if (lefwNumViaRuleLayers != 2)  // this routine has to be after two layers
      return LEFW_BAD_ORDER;        // be written
    if (!layerName || layerName == 0 || *layerName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   LAYER %s ;\n", layerName);
      encPrint(lefwFile, (char *)"      RECT %.11g %.11g %.11g %.11g ;\n", xl, yl, xh, yh);
      encPrint(lefwFile, (char *)"      SPACING %.11g BY %.11g ;\n", xSpacing, ySpacing);
      if (resistance) {
        encPrint(lefwFile, (char *)"      RESISTANCE %.11g ;\n", resistance);
        lefwLines++;
      }
    } else {
      fprintf(lefwFile, "   LAYER %s ;\n", layerName);
      fprintf(lefwFile, "      RECT %.11g %.11g %.11g %.11g ;\n", xl, yl, xh, yh);
      fprintf(lefwFile, "      SPACING %.11g BY %.11g ;\n", xSpacing, ySpacing);
      if (resistance) {
        fprintf(lefwFile, "      RESISTANCE %.11g ;\n", resistance);
        lefwLines++;
      }
    }
    lefwLines += 3;
    return LEFW_OK;
  }
  
  int lefwEndViaRuleGen(const char *viaRuleName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_VIARULEGEN_START && lefwState != LEFW_VIARULEGEN)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"END %s\n\n", viaRuleName);
    else
      fprintf(lefwFile, "END %s\n\n", viaRuleName);
  
    lefwLines++;
    lefwState            = LEFW_VIARULEGEN_END;
    lefwDidLayer         = 0;
    lefwNumViaRuleLayers = 0;
    return LEFW_OK;
  }
  
  int lefwStartNonDefaultRule(const char *ruleName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState == LEFW_NONDEFAULTRULE_START || lefwState == LEFW_NONDEFAULTRULE)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
  
    if (!ruleName || ruleName == 0 || *ruleName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"NONDEFAULTRULE %s\n", ruleName);
    else
      fprintf(lefwFile, "NONDEFAULTRULE %s\n", ruleName);
    lefwLines++;
  
    lefwSynArray[LEFW_NONDEFAULTRULE_START] = 1;
    lefwState                               = LEFW_NONDEFAULTRULE_START;
    lefwDidLayer                            = 0;  // hasn't set the layer yet
    lefwIsNonDefaultRule                    = 1;
    return LEFW_OK;
  }
  
  int lefwNonDefaultRuleHardspacing() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_NONDEFAULTRULE_START && lefwState != LEFW_NONDEFAULTRULE)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   HARDSPACING ;\n");
    else
      fprintf(lefwFile, "   HARDSPACING ;\n");
    return LEFW_OK;
  }
  
  int lefwNonDefaultRuleStartVia(const char *viaName, const char *isDefault) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState == LEFW_VIA_START || lefwState == LEFW_VIA
        || (lefwState != LEFW_NONDEFAULTRULE_START && lefwState != LEFW_NONDEFAULTRULE))
      return LEFW_BAD_ORDER;
  
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   VIA %s ", viaName);
      if (isDefault && strcmp(isDefault, "DEFAULT") == 0)
        encPrint(lefwFile, (char *)"DEFAULT");
      encPrint(lefwFile, (char *)"\n");
    } else {
      fprintf(lefwFile, "   VIA %s ", viaName);
      if (isDefault && strcmp(isDefault, "DEFAULT") == 0)
        fprintf(lefwFile, "DEFAULT");
      fprintf(lefwFile, "\n");
    }
    lefwLines++;
    lefwViaHasVal = 0;
  
    lefwSynArray[LEFW_VIA_START] = 1;
    lefwState                    = LEFW_VIA_START;
    lefwDidLayer                 = 0;  // hasn't set the layer yet
    return LEFW_OK;
  }
  
  int lefwNonDefaultRuleEndVia(const char *viaName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_VIA_START && lefwState != LEFW_VIA)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   END %s\n\n", viaName);
    else
      fprintf(lefwFile, "   END %s\n\n", viaName);
  
    lefwLines++;
    lefwState    = LEFW_NONDEFAULTRULE;
    lefwDidLayer = 0;
    return LEFW_OK;
  }
  
  int lefwNonDefaultRuleUseVia(const char *viaName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_NONDEFAULTRULE_START && lefwState != LEFW_NONDEFAULTRULE)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   USEVIA %s ;\n", viaName);
    else
      fprintf(lefwFile, "   USEVIA %s ;\n", viaName);
    return LEFW_OK;
  }
  
  int lefwNonDefaultRuleUseViaRule(const char *viaRuleName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_NONDEFAULTRULE_START && lefwState != LEFW_NONDEFAULTRULE)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   USEVIARULE %s ;\n", viaRuleName);
    else
      fprintf(lefwFile, "   USEVIARULE %s ;\n", viaRuleName);
    return LEFW_OK;
  }
  
  int lefwNonDefaultRuleMinCuts(const char *layerName, int numCuts) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_NONDEFAULTRULE_START && lefwState != LEFW_NONDEFAULTRULE)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   MINCUTS %s %d ;\n", layerName, numCuts);
    else
      fprintf(lefwFile, "   MINCUTS %s %d ;\n", layerName, numCuts);
    return LEFW_OK;
  }
  
  int lefwNonDefaultRuleLayer(const char *routingLayerName, double width, double minSpacing, double wireExtension, double resist,
                              double capacitance, double edgeCap) {
    lefwObsoleteNum = LEFW_NONDEFAULTRULELAYER;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_NONDEFAULTRULE_START && lefwState != LEFW_NONDEFAULTRULE)
      return LEFW_BAD_ORDER;
    if (!routingLayerName || routingLayerName == 0 || *routingLayerName == 0)
      return LEFW_BAD_DATA;
    if (versionNum >= 5.6 && (resist || capacitance || edgeCap))
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   LAYER %s\n", routingLayerName);
      encPrint(lefwFile, (char *)"      WIDTH %.11g ;\n", width);
      encPrint(lefwFile, (char *)"      SPACING %.11g ;\n", minSpacing);
      if (wireExtension) {
        encPrint(lefwFile, (char *)"      WIREEXTENSION %.11g ;\n", wireExtension);
        lefwLines++;
      }
      if (resist) {
        encPrint(lefwFile, (char *)"      RESISTANCE RPERSQ %.11g ;\n", resist);
        lefwLines++;
      }
      if (capacitance) {
        encPrint(lefwFile, (char *)"      CAPACITANCE CPERSQDIST %.11g ;\n", capacitance);
        lefwLines++;
      }
      if (edgeCap) {
        encPrint(lefwFile, (char *)"      EDGECAPACITANCE %.11g ;\n", edgeCap);
        lefwLines++;
      }
      encPrint(lefwFile, (char *)"   END %s\n\n", routingLayerName);
    } else {
      fprintf(lefwFile, "   LAYER %s\n", routingLayerName);
      fprintf(lefwFile, "      WIDTH %.11g ;\n", width);
      fprintf(lefwFile, "      SPACING %.11g ;\n", minSpacing);
      if (wireExtension) {
        fprintf(lefwFile, "      WIREEXTENSION %.11g ;\n", wireExtension);
        lefwLines++;
      }
      if (resist) {
        fprintf(lefwFile, "      RESISTANCE RPERSQ %.11g ;\n", resist);
        lefwLines++;
      }
      if (capacitance) {
        fprintf(lefwFile, "      CAPACITANCE CPERSQDIST %.11g ;\n", capacitance);
        lefwLines++;
      }
      if (edgeCap) {
        fprintf(lefwFile, "      EDGECAPACITANCE %.11g ;\n", edgeCap);
        lefwLines++;
      }
      fprintf(lefwFile, "   END %s\n\n", routingLayerName);
    }
  
    lefwLines                         = lefwLines + 4;
    lefwSynArray[LEFW_NONDEFAULTRULE] = 1;
    lefwState                         = LEFW_NONDEFAULTRULE;
    return LEFW_OK;
  }
  
  int lefwEndNonDefaultRule(const char *ruleName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_NONDEFAULTRULE_START && lefwState != LEFW_NONDEFAULTRULE && lefwState != LEFW_VIA_END
        && lefwState != LEFW_SPACING_END)
      return LEFW_BAD_ORDER;
    // can be right after a via or spacing defined in nondefaultrule
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"END %s\n\n", ruleName);
    else
      fprintf(lefwFile, "END %s\n\n", ruleName);
  
    lefwLines++;
    lefwState            = LEFW_NONDEFAULTRULE_END;
    lefwDidLayer         = 0;
    lefwIsNonDefaultRule = 0;
    return LEFW_OK;
  }
  
  int lefwStartSpacing() {
    lefwObsoleteNum = LEFW_SPACING;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState == LEFW_SPACING_START || lefwState == LEFW_SPACING)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END && (!lefwIsNonDefaultRule))  // spacing defined in nondefaultrule
      return LEFW_BAD_ORDER;                                                        // not of the ENDs
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"SPACING\n");
    else
      fprintf(lefwFile, "SPACING\n");
  
    lefwLines++;
    lefwState = LEFW_SPACING_START;
    return LEFW_OK;
  }
  
  int lefwSpacing(const char *layerName1, const char *layerName2, double minSpace,
                  const char *stack) {  // optioanl
    lefwObsoleteNum = LEFW_SPACING;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_SPACING_START && lefwState != LEFW_SPACING)
      return LEFW_BAD_ORDER;
    if (!layerName1 || layerName1 == 0 || *layerName1 == 0)
      return LEFW_BAD_DATA;
    if (!layerName2 || layerName2 == 0 || *layerName2 == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   SAMENET %s %s %.11g ", layerName1, layerName2, minSpace);
      if (stack && strcmp(stack, "STACK") == 0)
        encPrint(lefwFile, (char *)"STACK ");
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "   SAMENET %s %s %.11g ", layerName1, layerName2, minSpace);
      if (stack && strcmp(stack, "STACK") == 0)
        fprintf(lefwFile, "STACK ");
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState = LEFW_SPACING;
    return LEFW_OK;
  }
  
  int lefwEndSpacing() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_SPACING_START && lefwState != LEFW_SPACING)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"END SPACING\n\n");
    else
      fprintf(lefwFile, "END SPACING\n\n");
  
    lefwLines++;
    lefwState = LEFW_SPACING_END;
    return LEFW_OK;
  }
  
  int lefwUniversalNoiseMargin(double high, double low) {
    lefwObsoleteNum = LEFW_NOISEMARGIN;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (lefwSynArray[LEFW_NOISEMARGIN])
      return LEFW_ALREADY_DEFINED;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"UNIVERSALNOISEMARGIN %.11g %.11g ;\n", high, low);
    else
      fprintf(lefwFile, "UNIVERSALNOISEMARGIN %.11g %.11g ;\n", high, low);
    lefwSynArray[LEFW_NOISEMARGIN] = 1;
    return LEFW_OK;
  }
  
  int lefwEdgeRateThreshold1(double num) {
    lefwObsoleteNum = LEFW_THRESHOLD1;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (lefwSynArray[LEFW_THRESHOLD1])
      return LEFW_ALREADY_DEFINED;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"EDGERATETHRESHOLD1 %.11g ;\n", num);
    else
      fprintf(lefwFile, "EDGERATETHRESHOLD1 %.11g ;\n", num);
    lefwSynArray[LEFW_THRESHOLD1] = 1;
    return LEFW_OK;
  }
  
  int lefwEdgeRateThreshold2(double num) {
    lefwObsoleteNum = LEFW_THRESHOLD2;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (lefwSynArray[LEFW_THRESHOLD2])
      return LEFW_ALREADY_DEFINED;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"EDGERATETHRESHOLD2 %.11g ;\n", num);
    else
      fprintf(lefwFile, "EDGERATETHRESHOLD2 %.11g ;\n", num);
    lefwSynArray[LEFW_THRESHOLD2] = 1;
    return LEFW_OK;
  }
  
  int lefwEdgeRateScaleFactor(double num) {
    lefwObsoleteNum = LEFW_SCALEFACTOR;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (lefwSynArray[LEFW_SCALEFACTOR])
      return LEFW_ALREADY_DEFINED;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"EDGERATESCALEFACTOR %.11g ;\n", num);
    else
      fprintf(lefwFile, "EDGERATESCALEFACTOR %.11g ;\n", num);
    lefwSynArray[LEFW_SCALEFACTOR] = 1;
    return LEFW_OK;
  }
  
  int lefwStartNoiseTable(int num) {
    lefwObsoleteNum = LEFW_NOISETABLE_START;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState == LEFW_NOISETABLE_START || lefwState == LEFW_NOISETABLE)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (lefwSynArray[LEFW_NOISETABLE_START])
      return LEFW_ALREADY_DEFINED;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"NOISETABLE %d ;\n", num);
    else
      fprintf(lefwFile, "NOISETABLE %d ;\n", num);
  
    lefwLines++;
    lefwState                           = LEFW_NOISETABLE_START;
    lefwIsNoiseTable                    = 1;
    lefwIsEdgerate                      = 0;
    lefwSynArray[LEFW_NOISETABLE_START] = 1;
    return LEFW_OK;
  }
  
  // for both noisetable and correctiontable
  // Obsolete in 5.4
  int lefwEdgeRate(double num) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsNoiseTable && !lefwIsCorrectTable)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   EDGERATE %.11g ;\n", num);
    else
      fprintf(lefwFile, "   EDGERATE %.11g ;\n", num);
  
    lefwLines++;
    if (lefwState == LEFW_NOISETABLE_START)
      lefwState = LEFW_NOISETABLE;
    else if (lefwState == LEFW_CORRECTTABLE_START)
      lefwState = LEFW_CORRECTTABLE;
    lefwIsEdgerate  = 1;
    lefwIsOutResist = 0;
    return LEFW_OK;
  }
  
  // Obsolete in 5.4
  int lefwOutputResistance(int numResists, double *resistance) {
    int i;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsEdgerate)
      return LEFW_BAD_ORDER;
    if (lefwIsOutResist)
      return LEFW_BAD_ORDER;
  
    if (numResists <= 0)
      return LEFW_OK;
  
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   OUTPUTRESISTANCE ");
      for (i = 0; i < numResists; i++) {
        encPrint(lefwFile, (char *)"%.11g ", *resistance++);
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "   OUTPUTRESISTANCE ");
      for (i = 0; i < numResists; i++) {
        fprintf(lefwFile, "%.11g ", *resistance++);
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwIsOutResist = 1;
    lefwLines++;
    return LEFW_OK;
  }
  
  // Obsolete in 5.4
  int lefwVictims(int length, int numNoises, double *noises) {
    int i;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsOutResist)
      return LEFW_BAD_ORDER;
  
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      VICTIMLENGTH %d ;\n", length);
      if (numNoises <= 0)
        return LEFW_BAD_DATA;  // noises are required
      for (i = 0; i < numNoises; i++) {
        if (lefwIsNoiseTable)
          encPrint(lefwFile, (char *)"      VICTIMNOISE ");
        else
          encPrint(lefwFile, (char *)"      CORRECTIONFACTOR ");
        encPrint(lefwFile, (char *)"%.11g ", *noises++);
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      VICTIMLENGTH %d ;\n", length);
      if (numNoises <= 0)
        return LEFW_BAD_DATA;  // noises are required
      for (i = 0; i < numNoises; i++) {
        if (lefwIsNoiseTable)
          fprintf(lefwFile, "      VICTIMNOISE ");
        else
          fprintf(lefwFile, "      CORRECTIONFACTOR ");
        fprintf(lefwFile, "%.11g ", *noises++);
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    return LEFW_OK;
  }
  
  // Obsolete in 5.4
  int lefwEndNoiseTable() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_NOISETABLE_START && lefwState != LEFW_NOISETABLE)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"END NOISETABLE\n\n");
    else
      fprintf(lefwFile, "END NOISETABLE\n\n");
    lefwLines++;
  
    lefwState        = LEFW_NOISETABLE_END;
    lefwIsNoiseTable = 0;
    lefwIsOutResist  = 0;
    return LEFW_OK;
  }
  
  int lefwStartCorrectTable(int num) {
    lefwObsoleteNum = LEFW_CORRECTTABLE_START;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState == LEFW_CORRECTTABLE_START || lefwState == LEFW_CORRECTTABLE)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwSynArray[LEFW_CORRECTTABLE_START])
      return LEFW_ALREADY_DEFINED;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"CORRECTIONTABLE %d ;\n", num);
    else
      fprintf(lefwFile, "CORRECTIONTABLE %d ;\n", num);
  
    lefwLines++;
    lefwState                             = LEFW_CORRECTTABLE_START;
    lefwIsCorrectTable                    = 1;
    lefwIsEdgerate                        = 0;
    lefwSynArray[LEFW_CORRECTTABLE_START] = 1;
    return LEFW_OK;
  }
  
  // Obsolete in 5.4
  int lefwEndCorrectTable() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_CORRECTTABLE_START && lefwState != LEFW_CORRECTTABLE)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"END CORRECTIONTABLE\n\n");
    else
      fprintf(lefwFile, "END CORRECTIONTABLE\n\n");
    lefwLines++;
  
    lefwState        = LEFW_CORRECTTABLE_END;
    lefwIsNoiseTable = 0;
    return LEFW_OK;
  }
  
  int lefwMinFeature(double x, double y) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (lefwSynArray[LEFW_MINFEATURE])
      return LEFW_ALREADY_DEFINED;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"MINFEATURE %.11g %.11g ;\n", x, y);
    else
      fprintf(lefwFile, "MINFEATURE %.11g %.11g ;\n", x, y);
    lefwSynArray[LEFW_MINFEATURE] = 1;
    return LEFW_OK;
  }
  
  // *********************
  //  int lefwDielectric (float dielectric) {
  //    if (! lefwFile) return LEFW_UNINITIALIZED;
  //    if (! lefwDidInit) return LEFW_BAD_ORDER;
  //    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
  //       return LEFW_BAD_ORDER;
  //    if (lefwSynArray[LEFW_DIELECTRIC]) return LEFW_ALREADY_DEFINED;
  //    fprintf(lefwFile, "DIELECTRIC %.11g ;\n", dielectric);
  //    lefwSynArray[LEFW_DIELECTRIC] = 1;
  //    return LEFW_OK;
  //  }
  // ********************
  
  int lefwStartIrdrop() {
    lefwObsoleteNum = LEFW_IRDROP_START;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState == LEFW_IRDROP_START || lefwState == LEFW_IRDROP)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (lefwSynArray[LEFW_IRDROP_START])
      return LEFW_ALREADY_DEFINED;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"IRDROP\n");
    else
      fprintf(lefwFile, "IRDROP\n");
  
    lefwLines++;
    lefwState                       = LEFW_IRDROP_START;
    lefwSynArray[LEFW_IRDROP_START] = 1;
    return LEFW_OK;
  }
  
  // Obsolete in 5.4
  int lefwIrdropTable(const char *tableName, const char *currentsNvolts) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_IRDROP_START && lefwState != LEFW_IRDROP)
      return LEFW_BAD_ORDER;
    if (!tableName || tableName == 0 || *tableName == 0)
      return LEFW_BAD_DATA;
    if (!currentsNvolts || currentsNvolts == 0 || *currentsNvolts == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   TABLE %s %s ;\n", tableName, currentsNvolts);
    else
      fprintf(lefwFile, "   TABLE %s %s ;\n", tableName, currentsNvolts);
    lefwLines++;
  
    lefwState = LEFW_IRDROP;
    return LEFW_OK;
  }
  
  // Obsolete in 5.4
  int lefwEndIrdrop() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_IRDROP_START && lefwState != LEFW_IRDROP)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"END IRDROP\n\n");
    else
      fprintf(lefwFile, "END IRDROP\n\n");
    lefwLines++;
  
    lefwState = LEFW_IRDROP_END;
    return LEFW_OK;
  }
  
  int lefwSite(const char *siteName, const char *classType, const char *symmetry, double width, double height) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState == LEFW_SITE)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (!siteName || siteName == 0 || *siteName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"SITE %s\n", siteName);
      if (classType && strcmp(classType, "PAD") && strcmp(classType, "CORE"))
        return LEFW_BAD_DATA;
      encPrint(lefwFile, (char *)"   CLASS %s ;\n", classType);
      if (symmetry)
        encPrint(lefwFile, (char *)"   SYMMETRY %s ;\n", symmetry);
      encPrint(lefwFile, (char *)"   SIZE %.11g BY %.11g ;\n", width, height);
      // encPrint(lefwFile, (char*)"END %s\n\n", siteName);
    } else {
      fprintf(lefwFile, "SITE %s\n", siteName);
      if (classType && strcmp(classType, "PAD") && strcmp(classType, "CORE"))
        return LEFW_BAD_DATA;
      fprintf(lefwFile, "   CLASS %s ;\n", classType);
      if (symmetry)
        fprintf(lefwFile, "   SYMMETRY %s ;\n", symmetry);
      fprintf(lefwFile, "   SIZE %.11g BY %.11g ;\n", width, height);
      // a separate function call, lefwEndSite
      // fprintf(lefwFile, "END %s\n\n", siteName);
    }
  
    lefwLines               = lefwLines + 4;
    lefwSynArray[LEFW_SITE] = 1;
    lefwState               = LEFW_SITE;
    return LEFW_OK;
  }
  
  int lefwSiteRowPattern(const char *siteName, int orient) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_SITE)
      return LEFW_BAD_ORDER;
    if (!siteName || siteName == 0 || *siteName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ROWPATTERN %s %s ;\n", siteName, lefwOrient(orient));
    else
      fprintf(lefwFile, "   ROWPATTERN %s %s ;\n", siteName, lefwOrient(orient));
    lefwLines++;
    lefwState = LEFW_SITE;
    return LEFW_OK;
  }
  
  int lefwSiteRowPatternStr(const char *siteName, const char *orient) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_SITE)
      return LEFW_BAD_ORDER;
    if (!siteName || siteName == 0 || *siteName == 0)
      return LEFW_BAD_DATA;
    if (!orient || orient == 0 || *orient == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ROWPATTERN %s %s ;\n", siteName, orient);
    else
      fprintf(lefwFile, "   ROWPATTERN %s %s ;\n", siteName, orient);
    lefwLines++;
    lefwState = LEFW_SITE;
    return LEFW_OK;
  }
  
  int lefwEndSite(const char *siteName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_SITE)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"END %s\n\n", siteName);
    else
      fprintf(lefwFile, "END %s\n\n", siteName);
  
    lefwLines++;
    lefwState = LEFW_SITE_END;
    return LEFW_OK;
  }
  
  int lefwStartArray(const char *arrayName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState == LEFW_ARRAY_START || lefwState == LEFW_ARRAY)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (!arrayName || arrayName == 0 || *arrayName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"ARRAY %s\n", arrayName);
    else
      fprintf(lefwFile, "ARRAY %s\n", arrayName);
  
    lefwLines++;
    lefwState                      = LEFW_ARRAY_START;
    lefwSynArray[LEFW_ARRAY_START] = 1;
    lefwHasArrayReq                = 0;
    lefwIsArrayFloorp              = 0;
    return LEFW_OK;
  }
  
  int lefwArraySite(const char *name, double origX, double origY, int orient, double numX, double numY, double spaceX,
                    double spaceY) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_ARRAY_START && lefwState != LEFW_ARRAY)
      return LEFW_BAD_ORDER;
    if (!name || name == 0 || *name == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile,
               (char *)"   SITE %s %.11g %.11g %s DO %.11g BY %.11g STEP %.11g %.11g ;\n",
               name,
               origX,
               origY,
               lefwOrient(orient),
               numX,
               numY,
               spaceX,
               spaceY);
    else
      fprintf(lefwFile,
              "   SITE %s %.11g %.11g %s DO %.11g BY %.11g STEP %.11g %.11g ;\n",
              name,
              origX,
              origY,
              lefwOrient(orient),
              numX,
              numY,
              spaceX,
              spaceY);
  
    lefwLines++;
    lefwHasArrayReq = 1;
  
    lefwState = LEFW_ARRAY;
    return LEFW_OK;
  }
  
  int lefwArraySiteStr(const char *name, double origX, double origY, const char *orient, double numX, double numY, double spaceX,
                       double spaceY) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_ARRAY_START && lefwState != LEFW_ARRAY)
      return LEFW_BAD_ORDER;
    if (!name || name == 0 || *name == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile,
               (char *)"   SITE %s %.11g %.11g %s DO %.11g BY %.11g STEP %.11g %.11g ;\n",
               name,
               origX,
               origY,
               orient,
               numX,
               numY,
               spaceX,
               spaceY);
    else
      fprintf(lefwFile,
              "   SITE %s %.11g %.11g %s DO %.11g BY %.11g STEP %.11g %.11g ;\n",
              name,
              origX,
              origY,
              orient,
              numX,
              numY,
              spaceX,
              spaceY);
  
    lefwLines++;
    lefwHasArrayReq = 1;
  
    lefwState = LEFW_ARRAY;
    return LEFW_OK;
  }
  
  int lefwArrayCanplace(const char *name, double origX, double origY, int orient, double numX, double numY, double spaceX,
                        double spaceY) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_ARRAY_START && lefwState != LEFW_ARRAY)
      return LEFW_BAD_ORDER;
    if (!name || name == 0 || *name == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile,
               (char *)"   CANPLACE %s %.11g %.11g %s DO %.11g BY %.11g STEP %.11g %.11g ;\n",
               name,
               origX,
               origY,
               lefwOrient(orient),
               numX,
               numY,
               spaceX,
               spaceY);
    else
      fprintf(lefwFile,
              "   CANPLACE %s %.11g %.11g %s DO %.11g BY %.11g STEP %.11g %.11g ;\n",
              name,
              origX,
              origY,
              lefwOrient(orient),
              numX,
              numY,
              spaceX,
              spaceY);
  
    lefwLines++;
    lefwHasArrayReq = 1;
  
    lefwState = LEFW_ARRAY;
    return LEFW_OK;
  }
  
  int lefwArrayCanplaceStr(const char *name, double origX, double origY, const char *orient, double numX, double numY, double spaceX,
                           double spaceY) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_ARRAY_START && lefwState != LEFW_ARRAY)
      return LEFW_BAD_ORDER;
    if (!name || name == 0 || *name == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile,
               (char *)"   CANPLACE %s %.11g %.11g %s DO %.11g BY %.11g STEP %.11g %.11g ;\n",
               name,
               origX,
               origY,
               orient,
               numX,
               numY,
               spaceX,
               spaceY);
    else
      fprintf(lefwFile,
              "   CANPLACE %s %.11g %.11g %s DO %.11g BY %.11g STEP %.11g %.11g ;\n",
              name,
              origX,
              origY,
              orient,
              numX,
              numY,
              spaceX,
              spaceY);
  
    lefwLines++;
    lefwHasArrayReq = 1;
  
    lefwState = LEFW_ARRAY;
    return LEFW_OK;
  }
  
  int lefwArrayCannotoccupy(const char *name, double origX, double origY, int orient, double numX, double numY, double spaceX,
                            double spaceY) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_ARRAY_START && lefwState != LEFW_ARRAY)
      return LEFW_BAD_ORDER;
    if (!name || name == 0 || *name == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile,
               (char *)"   CANNOTOCCUPY %s %.11g %.11g %s DO %.11g BY %.11g STEP %.11g %.11g ;\n",
               name,
               origX,
               origY,
               lefwOrient(orient),
               numX,
               numY,
               spaceX,
               spaceY);
    else
      fprintf(lefwFile,
              "   CANNOTOCCUPY %s %.11g %.11g %s DO %.11g BY %.11g STEP %.11g %.11g ;\n",
              name,
              origX,
              origY,
              lefwOrient(orient),
              numX,
              numY,
              spaceX,
              spaceY);
  
    lefwLines++;
    lefwHasArrayReq = 1;
  
    lefwState = LEFW_ARRAY;
    return LEFW_OK;
  }
  
  int lefwArrayCannotoccupyStr(const char *name, double origX, double origY, const char *orient, double numX, double numY,
                               double spaceX, double spaceY) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_ARRAY_START && lefwState != LEFW_ARRAY)
      return LEFW_BAD_ORDER;
    if (!name || name == 0 || *name == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile,
               (char *)"   CANNOTOCCUPY %s %.11g %.11g %s DO %.11g BY %.11g STEP %.11g %.11g ;\n",
               name,
               origX,
               origY,
               orient,
               numX,
               numY,
               spaceX,
               spaceY);
    else
      fprintf(lefwFile,
              "   CANNOTOCCUPY %s %.11g %.11g %s DO %.11g BY %.11g STEP %.11g %.11g ;\n",
              name,
              origX,
              origY,
              orient,
              numX,
              numY,
              spaceX,
              spaceY);
  
    lefwLines++;
    lefwHasArrayReq = 1;
  
    lefwState = LEFW_ARRAY;
    return LEFW_OK;
  }
  
  int lefwArrayTracks(const char *xy, double start, int numTracks, double space, const char *layers) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_ARRAY_START && lefwState != LEFW_ARRAY)
      return LEFW_BAD_ORDER;
    if (!xy || xy == 0 || *xy == 0)
      return LEFW_BAD_DATA;
    if (strcmp(xy, "X") && strcmp(xy, "Y"))
      return LEFW_BAD_DATA;
    if (!layers || layers == 0 || *layers == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   TRACKS %s %.11g DO %d STEP %.11g LAYER %s ;\n", xy, start, numTracks, space, layers);
    else
      fprintf(lefwFile, "   TRACKS %s %.11g DO %d STEP %.11g LAYER %s ;\n", xy, start, numTracks, space, layers);
  
    lefwLines++;
    lefwHasArrayReq = 1;
  
    lefwState = LEFW_ARRAY;
    return LEFW_OK;
  }
  
  int lefwStartArrayFloorplan(const char *name) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_ARRAY_START && lefwState != LEFW_ARRAY)
      return LEFW_BAD_ORDER;
    if (lefwIsArrayFloorp)
      return LEFW_BAD_ORDER;
    if (!name || name == 0 || *name == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   FLOORPLAN %s\n", name);
    else
      fprintf(lefwFile, "   FLOORPLAN %s\n", name);
  
    lefwLines++;
    lefwHasArrayReq   = 1;
    lefwIsArrayFloorp = 1;
    return LEFW_OK;
  }
  
  int lefwArrayFloorplan(const char *site, const char *name, double origX, double origY, int orient, int numX, int numY,
                         double spaceX, double spaceY) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwIsArrayFloorp)
      return LEFW_BAD_ORDER;
    if (site && strcmp(site, "CANPLACE") && strcmp(site, "CANNOTOCCUPY"))
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile,
               (char *)"      %s %s %.11g %.11g %s DO %d BY %d STEP %.11g %.11g ;\n",
               site,
               name,
               origX,
               origY,
               lefwOrient(orient),
               numX,
               numY,
               spaceX,
               spaceY);
    else
      fprintf(lefwFile,
              "      %s %s %.11g %.11g %s DO %d BY %d STEP %.11g %.11g ;\n",
              site,
              name,
              origX,
              origY,
              lefwOrient(orient),
              numX,
              numY,
              spaceX,
              spaceY);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwArrayFloorplanStr(const char *site, const char *name, double origX, double origY, const char *orient, int numX, int numY,
                            double spaceX, double spaceY) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwIsArrayFloorp)
      return LEFW_BAD_ORDER;
    if (site && strcmp(site, "CANPLACE") && strcmp(site, "CANNOTOCCUPY"))
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile,
               (char *)"      %s %s %.11g %.11g %s DO %d BY %d STEP %.11g %.11g ;\n",
               site,
               name,
               origX,
               origY,
               orient,
               numX,
               numY,
               spaceX,
               spaceY);
    else
      fprintf(lefwFile,
              "      %s %s %.11g %.11g %s DO %d BY %d STEP %.11g %.11g ;\n",
              site,
              name,
              origX,
              origY,
              orient,
              numX,
              numY,
              spaceX,
              spaceY);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwEndArrayFloorplan(const char *name) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwIsArrayFloorp)
      return LEFW_BAD_ORDER;
    if (!name || name == 0 || *name == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   END %s\n\n", name);
    else
      fprintf(lefwFile, "   END %s\n\n", name);
  
    lefwLines++;
    lefwIsArrayFloorp = 0;
    return LEFW_OK;
  }
  
  int lefwArrayGcellgrid(const char *xy, double startXY, int colRows, double spaceXY) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_ARRAY_START && lefwState != LEFW_ARRAY)
      return LEFW_BAD_ORDER;
    if (!xy || xy == 0 || *xy == 0)
      return LEFW_BAD_DATA;
    if (strcmp(xy, "X") && strcmp(xy, "Y"))
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   GCELLGRID %s %.11g DO %d STEP %.11g ;\n", xy, startXY, colRows, spaceXY);
    else
      fprintf(lefwFile, "   GCELLGRID %s %.11g DO %d STEP %.11g ;\n", xy, startXY, colRows, spaceXY);
  
    lefwLines++;
    lefwHasArrayReq = 1;
  
    lefwState = LEFW_ARRAY;
    return LEFW_OK;
  }
  
  int lefwStartArrayDefaultCap(int size) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_ARRAY_START && lefwState != LEFW_ARRAY)
      return LEFW_BAD_ORDER;
    if (lefwIsArrayDef)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   DEFAULTCAP %d\n", size);
    else
      fprintf(lefwFile, "   DEFAULTCAP %d\n", size);
  
    lefwLines++;
    lefwIsArrayDef = 1;
    return LEFW_OK;
  }
  
  int lefwArrayDefaultCap(double numPins, double cap) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwIsArrayDef)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      MINPINS %.11g WIRECAP %.11g ;\n", numPins, cap);
    else
      fprintf(lefwFile, "      MINPINS %.11g WIRECAP %.11g ;\n", numPins, cap);
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwEndArrayDefaultCap() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwIsArrayDef)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   END DEFAULTCAP\n\n");
    else
      fprintf(lefwFile, "   END DEFAULTCAP\n\n");
  
    lefwLines++;
    lefwIsArrayDef = 0;
    return LEFW_OK;
  }
  
  int lefwEndArray(const char *arrayName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_ARRAY_START && lefwState != LEFW_ARRAY)
      return LEFW_BAD_ORDER;
    if (!arrayName || arrayName == 0 || *arrayName == 0)
      return LEFW_BAD_DATA;
    if (lefwIsFloorp || lefwIsArrayDef)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"END %s\n\n", arrayName);
    else
      fprintf(lefwFile, "END %s\n\n", arrayName);
  
    lefwLines++;
    lefwState = LEFW_ARRAY_END;
    return LEFW_OK;
  }
  
  int lefwStartMacro(const char *macroName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState == LEFW_MACRO_START || lefwState == LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (!macroName || macroName == 0 || *macroName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"MACRO %s\n", macroName);
    else
      fprintf(lefwFile, "MACRO %s\n", macroName);
  
    lefwLines++;
    lefwState          = LEFW_MACRO_START;
    lefwIsMacroDensity = 0;
    lefwIsMacroPin     = 0;
    lefwIsMacroObs     = 0;
    lefwIsMacroTiming  = 0;
    return LEFW_OK;
  }
  
  int lefwMacroClass(const char *value1, const char *value2) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (!value1 || value1 == 0 || *value1 == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt) {
      if (strcmp(value1, "RING") == 0)
        encPrint(lefwFile, (char *)"   CLASS %s ;\n", value1);
      else if (strcmp(value1, "BLOCK") == 0) {
        if (value2) {
          if (strcmp(value2, "BLACKBOX") && strcmp(value2, "SOFT"))
            return LEFW_BAD_DATA;
          encPrint(lefwFile, (char *)"   CLASS %s %s ;\n", value1, value2);
        } else
          encPrint(lefwFile, (char *)"   CLASS %s ;\n", value1);
      } else if (strcmp(value1, "COVER") == 0) {
        if (value2) {
          if (strcmp(value2, "BUMP"))
            return LEFW_BAD_DATA;
          encPrint(lefwFile, (char *)"   CLASS %s %s ;\n", value1, value2);
        } else
          encPrint(lefwFile, (char *)"   CLASS %s ;\n", value1);
      } else if (strcmp(value1, "PAD") == 0) {
        if (value2) {
          if (strcmp(value2, "INPUT") && strcmp(value2, "OUTPUT") && strcmp(value2, "INOUT") && strcmp(value2, "POWER")
              && strcmp(value2, "SPACER") && strcmp(value2, "AREAIO"))
            return LEFW_BAD_DATA;
          encPrint(lefwFile, (char *)"   CLASS %s %s ;\n", value1, value2);
        } else
          encPrint(lefwFile, (char *)"   CLASS %s ;\n", value1);
      } else if (strcmp(value1, "CORE") == 0) {
        if (value2) {
          if (strcmp(value2, "FEEDTHRU") && strcmp(value2, "TIEHIGH") && strcmp(value2, "TIELOW") && strcmp(value2, "SPACER")
              && strcmp(value2, "ANTENNACELL") && strcmp(value2, "WELLTAP"))
            return LEFW_BAD_DATA;
          encPrint(lefwFile, (char *)"   CLASS %s %s ;\n", value1, value2);
        } else
          encPrint(lefwFile, (char *)"   CLASS %s ;\n", value1);
      } else if (strcmp(value1, "ENDCAP") == 0) {
        if (value2) {
          if (strcmp(value2, "PRE") && strcmp(value2, "POST") && strcmp(value2, "TOPLEFT") && strcmp(value2, "TOPRIGHT")
              && strcmp(value2, "BOTTOMLEFT") && strcmp(value2, "BOTTOMRIGHT"))
            return LEFW_BAD_DATA;
          encPrint(lefwFile, (char *)"   CLASS %s %s ;\n", value1, value2);
        } else
          return LEFW_BAD_DATA;  // require 2nd value
      } else
        return LEFW_BAD_DATA;
    } else {
      if (strcmp(value1, "RING") == 0)
        fprintf(lefwFile, "   CLASS %s ;\n", value1);
      else if (strcmp(value1, "BLOCK") == 0) {
        if (value2) {
          if (strcmp(value2, "BLACKBOX") && strcmp(value2, "SOFT"))
            return LEFW_BAD_DATA;
          fprintf(lefwFile, "   CLASS %s %s ;\n", value1, value2);
        } else
          fprintf(lefwFile, "   CLASS %s ;\n", value1);
      } else if (strcmp(value1, "COVER") == 0) {
        if (value2) {
          if (strcmp(value2, "BUMP"))
            return LEFW_BAD_DATA;
          fprintf(lefwFile, "   CLASS %s %s ;\n", value1, value2);
        } else
          fprintf(lefwFile, "   CLASS %s ;\n", value1);
      } else if (strcmp(value1, "PAD") == 0) {
        if (value2) {
          if (strcmp(value2, "INPUT") && strcmp(value2, "OUTPUT") && strcmp(value2, "INOUT") && strcmp(value2, "POWER")
              && strcmp(value2, "SPACER") && strcmp(value2, "AREAIO"))
            return LEFW_BAD_DATA;
          fprintf(lefwFile, "   CLASS %s %s ;\n", value1, value2);
        } else
          fprintf(lefwFile, "   CLASS %s ;\n", value1);
      } else if (strcmp(value1, "CORE") == 0) {
        if (value2) {
          if (strcmp(value2, "FEEDTHRU") && strcmp(value2, "TIEHIGH") && strcmp(value2, "TIELOW") && strcmp(value2, "SPACER")
              && strcmp(value2, "ANTENNACELL") && strcmp(value2, "WELLTAP"))
            return LEFW_BAD_DATA;
          fprintf(lefwFile, "   CLASS %s %s ;\n", value1, value2);
        } else
          fprintf(lefwFile, "   CLASS %s ;\n", value1);
      } else if (strcmp(value1, "ENDCAP") == 0) {
        if (value2) {
          if (strcmp(value2, "PRE") && strcmp(value2, "POST") && strcmp(value2, "TOPLEFT") && strcmp(value2, "TOPRIGHT")
              && strcmp(value2, "BOTTOMLEFT") && strcmp(value2, "BOTTOMRIGHT"))
            return LEFW_BAD_DATA;
          fprintf(lefwFile, "   CLASS %s %s ;\n", value1, value2);
        } else
          return LEFW_BAD_DATA;  // require 2nd value
      } else
        return LEFW_BAD_DATA;
    }
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroFixedMask() {
    if (!lefwFile) {
      return LEFW_UNINITIALIZED;
    }
  
    if (!lefwDidInit) {
      return LEFW_BAD_ORDER;
    }
  
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO) {
      return LEFW_BAD_ORDER;
    }
  
    if (versionNum < 5.8) {
      return LEFW_WRONG_VERSION;
    }
  
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   FIXEDMASK ;\n");
    } else {
      fprintf(lefwFile, "   FIXEDMASK ;\n");
    }
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroSource(const char *value1) {
    lefwObsoleteNum = LEFW_MACRO_SOURCE;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.6)
      return LEFW_OBSOLETE;
    if (!value1 || value1 == 0 || *value1 == 0)
      return LEFW_BAD_DATA;
    if (strcmp(value1, "USER") == 0 || strcmp(value1, "GENERATE") == 0 || strcmp(value1, "BLOCK") == 0)
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)"   SOURCE %s ;\n", value1);
      else
        fprintf(lefwFile, "   SOURCE %s ;\n", value1);
    else
      return LEFW_BAD_DATA;
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroForeign(const char *name, double xl, double yl,
                       int orient) {  // optional
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (!name || name == 0 || *name == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   FOREIGN %s ", name);
      if (xl || yl) {
        encPrint(lefwFile, (char *)"%.11g %.11g ", xl, yl);
        if (orient >= 0 && orient <= 7)
          encPrint(lefwFile, (char *)"%s ", lefwOrient(orient));
      } else if (orient > 0 && orient <= 7) {  // assume user has 0, 0 pt
        encPrint(lefwFile, (char *)"%.11g %.11g ", xl, yl);
        encPrint(lefwFile, (char *)"%s ", lefwOrient(orient));
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "   FOREIGN %s ", name);
      if (xl || yl) {
        fprintf(lefwFile, "%.11g %.11g ", xl, yl);
        if (orient >= 0 && orient <= 7)
          fprintf(lefwFile, "%s ", lefwOrient(orient));
      } else if (orient > 0 && orient <= 7) {  // assume user has 0, 0 pt
        fprintf(lefwFile, "%.11g %.11g ", xl, yl);
        fprintf(lefwFile, "%s ", lefwOrient(orient));
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroForeignStr(const char *name, double xl, double yl,
                          const char *orient) {  // optional
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (!name || name == 0 || *name == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   FOREIGN %s ", name);
      if (xl || yl) {
        encPrint(lefwFile, (char *)"%.11g %.11g ", xl, yl);
        if (orient && *orient != '\0')
          encPrint(lefwFile, (char *)"%s ", orient);
      } else if (orient && *orient != '\0') {  // assume user has 0, 0 pt
        encPrint(lefwFile, (char *)"%.11g %.11g ", xl, yl);
        encPrint(lefwFile, (char *)"%s ", orient);
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "   FOREIGN %s ", name);
      if (xl || yl) {
        fprintf(lefwFile, "%.11g %.11g ", xl, yl);
        if (orient && *orient != '\0')
          fprintf(lefwFile, "%s ", orient);
      } else if (orient && *orient != '\0') {  // assume user has 0, 0 pt
        fprintf(lefwFile, "%.11g %.11g ", xl, yl);
        fprintf(lefwFile, "%s ", orient);
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroOrigin(double xl,
                      double yl) {  // optional
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ORIGIN %.11g %.11g ;\n", xl, yl);
    else
      fprintf(lefwFile, "   ORIGIN %.11g %.11g ;\n", xl, yl);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroEEQ(const char *macroName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (!macroName || macroName == 0 || *macroName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   EEQ %s ;\n", macroName);
    else
      fprintf(lefwFile, "   EEQ %s ;\n", macroName);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroLEQ(const char *macroName) {
    lefwObsoleteNum = LEFW_MACRO_LEQ;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.6)
      return LEFW_OBSOLETE;
    if (!macroName || macroName == 0 || *macroName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   LEQ %s ;\n", macroName);
    else
      fprintf(lefwFile, "   LEQ %s ;\n", macroName);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroSize(double width, double height) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   SIZE %.11g BY %.11g ;\n", width, height);
    else
      fprintf(lefwFile, "   SIZE %.11g BY %.11g ;\n", width, height);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroSymmetry(const char *symmetry) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (!symmetry || symmetry == 0 || *symmetry == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   SYMMETRY %s ;\n", symmetry);
    else
      fprintf(lefwFile, "   SYMMETRY %s ;\n", symmetry);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroSite(const char *siteName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (!siteName || siteName == 0 || *siteName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   SITE %s ;\n", siteName);
    else
      fprintf(lefwFile, "   SITE %s ;\n", siteName);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroSitePattern(const char *name, double origX, double origY, int orient, int numX, int numY, double spaceX,
                           double spaceY) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (!name || name == 0 || *name == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   SITE %s ", name);
      if (origX || origY || (orient != 1)) {
        encPrint(lefwFile, (char *)"%.11g %.11g %s ", origX, origY, lefwOrient(orient));
        if (numX || numY || spaceX || spaceY)
          encPrint(lefwFile, (char *)"DO %d BY %d STEP %.11g %.11g ", numX, numY, spaceX, spaceY);
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "   SITE %s ", name);
      if (origX || origY || (orient != 1)) {
        fprintf(lefwFile, "%.11g %.11g %s ", origX, origY, lefwOrient(orient));
        if (numX || numY || spaceX || spaceY)
          fprintf(lefwFile, "DO %d BY %d STEP %.11g %.11g ", numX, numY, spaceX, spaceY);
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroSitePatternStr(const char *name, double origX, double origY, const char *orient, int numX, int numY, double spaceX,
                              double spaceY) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (!name || name == 0 || *name == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"   SITE %s ", name);
      if (origX || origY || orient) {
        encPrint(lefwFile, (char *)"%.11g %.11g %s ", origX, origY, orient);
        if (numX || numY || spaceX || spaceY)
          encPrint(lefwFile, (char *)"DO %d BY %d STEP %.11g %.11g ", numX, numY, spaceX, spaceY);
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "   SITE %s ", name);
      if (origX || origY || orient) {
        fprintf(lefwFile, "%.11g %.11g %s ", origX, origY, orient);
        if (numX || numY || spaceX || spaceY)
          fprintf(lefwFile, "DO %d BY %d STEP %.11g %.11g ", numX, numY, spaceX, spaceY);
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPower(double power) {
    lefwObsoleteNum = LEFW_MACRO_POWER;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   POWER %.11g ;\n", power);
    else
      fprintf(lefwFile, "   POWER %.11g ;\n", power);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwEndMacro(const char *macroName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (!macroName || macroName == 0 || *macroName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"END %s\n\n", macroName);
    else
      fprintf(lefwFile, "END %s\n\n", macroName);
  
    lefwLines++;
    lefwState = LEFW_MACRO_END;
    return LEFW_OK;
  }
  
  int lefwStartMacroDensity(const char *layerName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (lefwIsMacroDensity)
      return LEFW_BAD_ORDER;
    if (!layerName || layerName == 0 || *layerName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   DENSITY %s\n", layerName);
    else
      fprintf(lefwFile, "   DENSITY %s\n", layerName);
  
    lefwState          = LEFW_MACRO;
    lefwIsMacroDensity = 1;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwMacroDensityLayerRect(double x1, double y1, double x2, double y2, double densityValue) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroDensity)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      RECT %.11g %.11g %.11g %.11g %.11g ;\n", x1, y1, x2, y2, densityValue);
    else
      fprintf(lefwFile, "      RECT %.11g %.11g %.11g %.11g %.11g ;\n", x1, y1, x2, y2, densityValue);
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwEndMacroDensity() {
    if (!lefwIsMacroDensity)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   END\n\n");
    else
      fprintf(lefwFile, "   END\n\n");
  
    lefwLines++;
    lefwIsMacroDensity = 0;
    return LEFW_OK;
  }
  
  int lefwStartMacroPin(const char *pinName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (!pinName || pinName == 0 || *pinName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   PIN %s\n", pinName);
    else
      fprintf(lefwFile, "   PIN %s\n", pinName);
  
    lefwIsMacroPin     = 1;
    lefwIsMacroPinPort = 0;  // port within macropin
    lefwLines++;
    lefwAMaxAreaCar     = 0;  // reset
    lefwAMaxSideAreaCar = 0;  // reset
    lefwAMaxCutCar      = 0;  // reset
    return LEFW_OK;
  }
  
  int lefwMacroPinTaperRule(const char *ruleName) {  // opitonal
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (!ruleName || ruleName == 0 || *ruleName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      TAPERRULE %s ;\n", ruleName);
    else
      fprintf(lefwFile, "      TAPERRULE %s ;\n", ruleName);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinForeign(const char *name, double xl, double yl,
                          int orient) {  // optional
    lefwObsoleteNum = LEFW_MACRO_PINFOREIGN;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.6)
      return LEFW_OBSOLETE;
    if (!name || name == 0 || *name == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      FOREIGN %s ", name);
      if (xl || yl) {
        encPrint(lefwFile, (char *)"STRUCTURE %.11g %.11g ", xl, yl);
        if (orient >= 0 && orient <= 7)
          encPrint(lefwFile, (char *)"%s ", lefwOrient(orient));
      } else if (orient > 0 && orient <= 7) {  // assume user has 0 0 for pt
        encPrint(lefwFile, (char *)"STRUCTURE %.11g %.11g ", xl, yl);
        encPrint(lefwFile, (char *)"%s ", lefwOrient(orient));
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      FOREIGN %s ", name);
      if (xl || yl) {
        fprintf(lefwFile, "STRUCTURE %.11g %.11g ", xl, yl);
        if (orient >= 0 && orient <= 7)
          fprintf(lefwFile, "%s ", lefwOrient(orient));
      } else if (orient > 0 && orient <= 7) {  // assume user has 0 0 for pt
        fprintf(lefwFile, "STRUCTURE %.11g %.11g ", xl, yl);
        fprintf(lefwFile, "%s ", lefwOrient(orient));
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinForeignStr(const char *name, double xl,
                             double      yl,        // optional
                             const char *orient) {  // optional
    lefwObsoleteNum = LEFW_MACRO_PINFOREIGN;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.6)
      return LEFW_OBSOLETE;
    if (!name || name == 0 || *name == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      FOREIGN %s ", name);
      if (xl || yl) {
        encPrint(lefwFile, (char *)"STRUCTURE %.11g %.11g ", xl, yl);
        if (orient && *orient != '\0')
          encPrint(lefwFile, (char *)"%s ", orient);
      } else if (orient && *orient != '\0') {  // assume user has 0 0 for pt
        encPrint(lefwFile, (char *)"STRUCTURE %.11g %.11g ", xl, yl);
        encPrint(lefwFile, (char *)"%s ", orient);
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      FOREIGN %s ", name);
      if (xl || yl) {
        fprintf(lefwFile, "STRUCTURE %.11g %.11g ", xl, yl);
        if (orient && *orient != '\0')
          fprintf(lefwFile, "%s ", orient);
      } else if (orient && *orient != '\0') {  // assume user has 0 0 for pt
        fprintf(lefwFile, "STRUCTURE %.11g %.11g ", xl, yl);
        fprintf(lefwFile, "%s ", orient);
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinLEQ(const char *pinName) {
    lefwObsoleteNum = LEFW_MACRO_PINLEQ;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.6)
      return LEFW_OBSOLETE;
    if (!pinName || pinName == 0 || *pinName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      LEQ %s ;\n", pinName);
    else
      fprintf(lefwFile, "      LEQ %s ;\n", pinName);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinDirection(const char *direction) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (!direction || direction == 0 || *direction == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      DIRECTION %s ;\n", direction);
    else
      fprintf(lefwFile, "      DIRECTION %s ;\n", direction);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinUse(const char *use) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (!use || use == 0 || *use == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      USE %s ;\n", use);
    else
      fprintf(lefwFile, "      USE %s ;\n", use);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinShape(const char *name) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt) {
      if (!name || name == 0 || *name == 0)
        encPrint(lefwFile, (char *)"      SHAPE ;\n");
      else
        encPrint(lefwFile, (char *)"      SHAPE %s ;\n", name);
    } else {
      if (!name || name == 0 || *name == 0)
        fprintf(lefwFile, "      SHAPE ;\n");
      else
        fprintf(lefwFile, "      SHAPE %s ;\n", name);
    }
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinMustjoin(const char *name) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (!name || name == 0 || *name == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      MUSTJOIN %s ;\n", name);
    else
      fprintf(lefwFile, "      MUSTJOIN %s ;\n", name);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinNetExpr(const char *name) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (!name || name == 0 || *name == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      NETEXPR \"%s\" ;\n", name);
    else
      fprintf(lefwFile, "      NETEXPR \"%s\" ;\n", name);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinSupplySensitivity(const char *pinName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (!pinName || pinName == 0 || *pinName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      SUPPLYSENSITIVITY %s ;\n", pinName);
    else
      fprintf(lefwFile, "      SUPPLYSENSITIVITY %s ;\n", pinName);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinGroundSensitivity(const char *pinName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (!pinName || pinName == 0 || *pinName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      GROUNDSENSITIVITY %s ;\n", pinName);
    else
      fprintf(lefwFile, "      GROUNDSENSITIVITY %s ;\n", pinName);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinOutputnoisemargin(int high, int low) {
    lefwObsoleteNum = LEFW_MACRO_OUTPUTNOISEMARGIN;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      OUTPUTNOISEMARGIN %d %d ;\n", high, low);
    else
      fprintf(lefwFile, "      OUTPUTNOISEMARGIN %d %d ;\n", high, low);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinOutputresistance(int high, int low) {
    lefwObsoleteNum = LEFW_MACRO_OUTPUTRESISTANCE;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      OUTPUTRESISTANCE %d %d ;\n", high, low);
    else
      fprintf(lefwFile, "      OUTPUTRESISTANCE %d %d ;\n", high, low);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinInputnoisemargin(int high, int low) {
    lefwObsoleteNum = LEFW_MACRO_INPUTNOISEMARGIN;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      INPUTNOISEMARGIN %d %d ;\n", high, low);
    else
      fprintf(lefwFile, "      INPUTNOISEMARGIN %d %d ;\n", high, low);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinPower(double power) {
    lefwObsoleteNum = LEFW_MACRO_POWER;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      POWER %.11g ;\n", power);
    else
      fprintf(lefwFile, "      POWER %.11g ;\n", power);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinLeakage(double leakage) {
    lefwObsoleteNum = LEFW_MACRO_LEAKAGE;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      LEAKAGE %.11g ;\n", leakage);
    else
      fprintf(lefwFile, "      LEAKAGE %.11g ;\n", leakage);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinCapacitance(double capacitance) {
    lefwObsoleteNum = LEFW_MACRO_CAPACITANCE;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      CAPACITANCE %.11g ;\n", capacitance);
    else
      fprintf(lefwFile, "      CAPACITANCE %.11g ;\n", capacitance);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinResistance(double resistance) {
    lefwObsoleteNum = LEFW_MACRO_RESISTANCE;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      RESISTANCE %.11g ;\n", resistance);
    else
      fprintf(lefwFile, "      RESISTANCE %.11g ;\n", resistance);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinPulldownres(double resistance) {
    lefwObsoleteNum = LEFW_MACRO_PULLDOWNRES;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      PULLDOWNRES %.11g ;\n", resistance);
    else
      fprintf(lefwFile, "      PULLDOWNRES %.11g ;\n", resistance);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinTieoffr(double resistance) {
    lefwObsoleteNum = LEFW_MACRO_TIEOFFR;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      TIEOFFR %.11g ;\n", resistance);
    else
      fprintf(lefwFile, "      TIEOFFR %.11g ;\n", resistance);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinVHI(double voltage) {
    lefwObsoleteNum = LEFW_MACRO_VHI;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      VHI %.11g ;\n", voltage);
    else
      fprintf(lefwFile, "      VHI %.11g ;\n", voltage);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinVLO(double voltage) {
    lefwObsoleteNum = LEFW_MACRO_VLO;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      VLO %.11g ;\n", voltage);
    else
      fprintf(lefwFile, "      VLO %.11g ;\n", voltage);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinRisevoltagethreshold(double voltage) {
    lefwObsoleteNum = LEFW_MACRO_RISEVOLTAGETHRESHOLD;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      RISEVOLTAGETHRESHOLD %.11g ;\n", voltage);
    else
      fprintf(lefwFile, "      RISEVOLTAGETHRESHOLD %.11g ;\n", voltage);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinFallvoltagethreshold(double voltage) {
    lefwObsoleteNum = LEFW_MACRO_FALLVOLTAGETHRESHOLD;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      FALLVOLTAGETHRESHOLD %.11g ;\n", voltage);
    else
      fprintf(lefwFile, "      FALLVOLTAGETHRESHOLD %.11g ;\n", voltage);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinRisethresh(double capacitance) {
    lefwObsoleteNum = LEFW_MACRO_RISETHRESH;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      RISETHRESH %.11g ;\n", capacitance);
    else
      fprintf(lefwFile, "      RISETHRESH %.11g ;\n", capacitance);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinFallthresh(double capacitance) {
    lefwObsoleteNum = LEFW_MACRO_FALLTHRESH;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      FALLTHRESH %.11g ;\n", capacitance);
    else
      fprintf(lefwFile, "      FALLTHRESH %.11g ;\n", capacitance);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinRisesatcur(double current) {
    lefwObsoleteNum = LEFW_MACRO_RISESATCUR;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      RISESATCUR %.11g ;\n", current);
    else
      fprintf(lefwFile, "      RISESATCUR %.11g ;\n", current);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinFallsatcur(double current) {
    lefwObsoleteNum = LEFW_MACRO_FALLSATCUR;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      FALLSATCUR %.11g ;\n", current);
    else
      fprintf(lefwFile, "      FALLSATCUR %.11g ;\n", current);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinCurrentsource(const char *name) {
    lefwObsoleteNum = LEFW_MACRO_FALLCURRENTSOURCE;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (!name || name == 0 || *name == 0)
      return LEFW_BAD_DATA;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (strcmp(name, "ACTIVE") && strcmp(name, "RESISTIVE"))
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      CURRENTSOURCE %s ;\n", name);
    else
      fprintf(lefwFile, "      CURRENTSOURCE %s ;\n", name);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinIV_Tables(const char *lowName, const char *highName) {
    lefwObsoleteNum = LEFW_MACRO_IV_TABLES;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (!lowName || lowName == 0 || *lowName == 0)
      return LEFW_BAD_DATA;
    if (!highName || highName == 0 || *highName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      IV_TABLES %s %s ;\n", lowName, highName);
    else
      fprintf(lefwFile, "      IV_TABLES %s %s ;\n", lowName, highName);
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinAntennasize(double value, const char *layerName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (lefwAntenna54)
      return LEFW_MIX_VERSION_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      ANTENNASIZE %.11g ", value);
      if (layerName)
        encPrint(lefwFile, (char *)"LAYER %s ", layerName);
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      ANTENNASIZE %.11g ", value);
      if (layerName)
        fprintf(lefwFile, "LAYER %s ", layerName);
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState     = LEFW_MACRO;
    lefwAntenna53 = 1;
    return LEFW_OK;
  }
  
  int lefwMacroPinAntennaMetalArea(double value, const char *layerName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      ANTENNAMETALAREA %.11g ", value);
      if (layerName)
        encPrint(lefwFile, (char *)"LAYER %s ", layerName);
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      ANTENNAMETALAREA %.11g ", value);
      if (layerName)
        fprintf(lefwFile, "LAYER %s ", layerName);
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState = LEFW_MACRO;
    return LEFW_OK;
  }
  
  int lefwMacroPinAntennaMetalLength(double value, const char *layerName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (lefwAntenna54)
      return LEFW_MIX_VERSION_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      ANTENNAMETALLENGTH %.11g ", value);
      if (layerName)
        encPrint(lefwFile, (char *)"LAYER %s ", layerName);
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      ANTENNAMETALLENGTH %.11g ", value);
      if (layerName)
        fprintf(lefwFile, "LAYER %s ", layerName);
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState     = LEFW_MACRO;
    lefwAntenna53 = 1;
    return LEFW_OK;
  }
  
  int lefwMacroPinAntennaPartialMetalArea(double value, const char *layerName) {
    lefw54Num = LEFW_ANTENNAPARTIALMETALAREA;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwAntenna53)
      return LEFW_MIX_VERSION_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      ANTENNAPARTIALMETALAREA %.11g ", value);
      if (layerName)
        encPrint(lefwFile, (char *)"LAYER %s ", layerName);
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      ANTENNAPARTIALMETALAREA %.11g ", value);
      if (layerName)
        fprintf(lefwFile, "LAYER %s ", layerName);
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState     = LEFW_MACRO;
    lefwAntenna54 = 1;
    return LEFW_OK;
  }
  
  int lefwMacroPinAntennaPartialMetalSideArea(double value, const char *layerName) {
    lefw54Num = LEFW_ANTENNAPARTIALMETALSIDEAREA;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwAntenna53)
      return LEFW_MIX_VERSION_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      ANTENNAPARTIALMETALSIDEAREA %.11g ", value);
      if (layerName)
        encPrint(lefwFile, (char *)"LAYER %s ", layerName);
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      ANTENNAPARTIALMETALSIDEAREA %.11g ", value);
      if (layerName)
        fprintf(lefwFile, "LAYER %s ", layerName);
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState     = LEFW_MACRO;
    lefwAntenna54 = 1;
    return LEFW_OK;
  }
  
  int lefwMacroPinAntennaPartialCutArea(double value, const char *layerName) {
    lefw54Num = LEFW_ANTENNAPARTIALCUTAREA;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwAntenna53)
      return LEFW_MIX_VERSION_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      ANTENNAPARTIALCUTAREA %.11g ", value);
      if (layerName)
        encPrint(lefwFile, (char *)"LAYER %s ", layerName);
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      ANTENNAPARTIALCUTAREA %.11g ", value);
      if (layerName)
        fprintf(lefwFile, "LAYER %s ", layerName);
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState     = LEFW_MACRO;
    lefwAntenna54 = 1;
    return LEFW_OK;
  }
  
  int lefwMacroPinAntennaDiffArea(double value, const char *layerName) {
    lefw54Num = LEFW_ANTENNADIFFAREA;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwAntenna53)
      return LEFW_MIX_VERSION_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      ANTENNADIFFAREA %.11g ", value);
      if (layerName)
        encPrint(lefwFile, (char *)"LAYER %s ", layerName);
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      ANTENNADIFFAREA %.11g ", value);
      if (layerName)
        fprintf(lefwFile, "LAYER %s ", layerName);
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState     = LEFW_MACRO;
    lefwAntenna54 = 1;
    return LEFW_OK;
  }
  
  int lefwMacroPinAntennaModel(const char *oxide) {
    lefw54Num = LEFW_ANTENNAGATEAREA;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwAntenna53)
      return LEFW_MIX_VERSION_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      ANTENNAMODEL %s ;\n", oxide);
    } else {
      fprintf(lefwFile, "      ANTENNAMODEL %s ;\n", oxide);
    }
  
    lefwLines++;
    lefwState     = LEFW_MACRO;
    lefwAntenna54 = 1;
    return LEFW_OK;
  }
  
  int lefwMacroPinAntennaGateArea(double value, const char *layerName) {
    lefw54Num = LEFW_ANTENNAGATEAREA;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwAntenna53)
      return LEFW_MIX_VERSION_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      ANTENNAGATEAREA %.11g ", value);
      if (layerName)
        encPrint(lefwFile, (char *)"LAYER %s ", layerName);
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      ANTENNAGATEAREA %.11g ", value);
      if (layerName)
        fprintf(lefwFile, "LAYER %s ", layerName);
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState     = LEFW_MACRO;
    lefwAntenna54 = 1;
    return LEFW_OK;
  }
  
  int lefwMacroPinAntennaMaxAreaCar(double value, const char *layerName) {
    lefw54Num = LEFW_ANTENNAMAXAREACAR;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (lefwAMaxAreaCar)
      return LEFW_BAD_DATA;  // ANTENNAMAXAREACAR has defined
    // more than once
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwAntenna53)
      return LEFW_MIX_VERSION_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      ANTENNAMAXAREACAR %.11g ", value);
      if (layerName)
        encPrint(lefwFile, (char *)"LAYER %s ", layerName);
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      ANTENNAMAXAREACAR %.11g ", value);
      if (layerName)
        fprintf(lefwFile, "LAYER %s ", layerName);
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState     = LEFW_MACRO;
    lefwAntenna54 = 1;
    return LEFW_OK;
  }
  
  int lefwMacroPinAntennaMaxSideAreaCar(double value, const char *layerName) {
    lefw54Num = LEFW_ANTENNAMAXSIDEAREACAR;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (lefwAMaxSideAreaCar)
      return LEFW_BAD_DATA;  // ANTENNAMAXSIDEAREACAR has
    // defined more than once
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwAntenna53)
      return LEFW_MIX_VERSION_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      ANTENNAMAXSIDEAREACAR %.11g ", value);
      if (layerName)
        encPrint(lefwFile, (char *)"LAYER %s ", layerName);
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      ANTENNAMAXSIDEAREACAR %.11g ", value);
      if (layerName)
        fprintf(lefwFile, "LAYER %s ", layerName);
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState     = LEFW_MACRO;
    lefwAntenna54 = 1;
    return LEFW_OK;
  }
  
  int lefwMacroPinAntennaMaxCutCar(double value, const char *layerName) {
    lefw54Num = LEFW_ANTENNAMAXCUTCAR;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (lefwAMaxCutCar)
      return LEFW_BAD_DATA;  // ANTENNAMAXCUTCAR has
    // defined more than once
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwAntenna53)
      return LEFW_MIX_VERSION_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      ANTENNAMAXCUTCAR %.11g ", value);
      if (layerName)
        encPrint(lefwFile, (char *)"LAYER %s ", layerName);
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      ANTENNAMAXCUTCAR %.11g ", value);
      if (layerName)
        fprintf(lefwFile, "LAYER %s ", layerName);
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwState     = LEFW_MACRO;
    lefwAntenna54 = 1;
    return LEFW_OK;
  }
  
  int lefwEndMacroPin(const char *pinName) {
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (!pinName || pinName == 0 || *pinName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   END %s\n\n", pinName);
    else
      fprintf(lefwFile, "   END %s\n\n", pinName);
  
    lefwLines++;
    lefwIsMacroPin = 0;
    return LEFW_OK;
  }
  
  int lefwStartMacroPinPort(const char *classType) {  // optional
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPin)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt) {
      if (classType) {
        if (strcmp(classType, "NONE") && strcmp(classType, "CORE"))
          return LEFW_BAD_DATA;
        encPrint(lefwFile, (char *)"      PORT CLASS %s ;\n", classType);
      } else
        encPrint(lefwFile, (char *)"      PORT \n");
    } else {
      if (classType) {
        if (strcmp(classType, "NONE") && strcmp(classType, "CORE") && strcmp(classType, "BUMP"))
          return LEFW_BAD_DATA;
        fprintf(lefwFile, "      PORT CLASS %s ;\n", classType);
      } else
        fprintf(lefwFile, "      PORT \n");
    }
  
    lefwLines++;
    lefwIsMacroPinPort      = 1;
    lefwIsMacroPinPortLayer = 0;
    lefwSpacingVal          = 0;
    lefwWidthVal            = 0;
    return LEFW_OK;
  }
  
  int lefwMacroPinPortLayer(const char *layerName, double spacing) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPinPort)
      return LEFW_BAD_ORDER;
    if (!layerName || layerName == 0 || *layerName == 0)
      return LEFW_BAD_DATA;
    if (lefwWidthVal)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"         LAYER %s ", layerName);
      if (spacing)
        encPrint(lefwFile, (char *)"SPACING %.11g ", spacing);
      encPrint(lefwFile, (char *)";\n ");
    } else {
      fprintf(lefwFile, "         LAYER %s ", layerName);
      if (spacing)
        fprintf(lefwFile, "SPACING %.11g ", spacing);
      fprintf(lefwFile, ";\n ");
    }
    lefwLines++;
    lefwIsMacroPinPortLayer = 1;
    lefwSpacingVal          = 1;
    return LEFW_OK;
  }
  
  int lefwMacroPinPortDesignRuleWidth(const char *layerName, double width) {
    lefw54Num = LEFW_DESIGNRULEWIDTH;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPinPort)
      return LEFW_BAD_ORDER;
    if (!layerName || layerName == 0 || *layerName == 0)
      return LEFW_BAD_DATA;
    if (lefwSpacingVal)
      return LEFW_BAD_DATA;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"         LAYER %s ", layerName);
      if (width)
        encPrint(lefwFile, (char *)"DESIGNRULEWIDTH %.11g ", width);
      encPrint(lefwFile, (char *)";\n ");
    } else {
      fprintf(lefwFile, "         LAYER %s ", layerName);
      if (width)
        fprintf(lefwFile, "DESIGNRULEWIDTH %.11g ", width);
      fprintf(lefwFile, ";\n ");
    }
    lefwLines++;
    lefwIsMacroPinPortLayer = 1;
    lefwWidthVal            = 1;
    return LEFW_OK;
  }
  
  int lefwMacroPinPortLayerWidth(double width) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPinPortLayer)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"         WIDTH %.11g ;\n", width);
    else
      fprintf(lefwFile, "         WIDTH %.11g ;\n", width);
    lefwLines++;
    lefwIsMacroPinPortLayer = 1;
    return LEFW_OK;
  }
  
  int lefwMacroPinPortLayerPath(int num_paths, double *xl, double *yl, int numX,
                                int    numY,  // optional
                                double spaceX,
                                double spaceY,  // optional
                                int    mask) {     // optional
    int i, numItem;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPinPortLayer)
      return LEFW_BAD_ORDER;
    if (mask && versionNum < 5.8) {
      return LEFW_WRONG_VERSION;
    }
  
    if (!lefwValidateMaskNumber(mask)) {
      return LEFW_BAD_DATA;
    }
  
    if (lefwWriteEncrypt) {
      if (numX || numY || spaceX || spaceY) {
        if (mask) {
          encPrint(lefwFile, (char *)"         PATH MASK %d ITERATE ", mask);
        } else {
          encPrint(lefwFile, (char *)"         PATH ITERATE ");
        }
        for (i = 0; i < num_paths; i++) {
          if (i == 0)
            encPrint(lefwFile, (char *)"%.11g %.11g\n", xl[i], yl[i]);
          else
            encPrint(lefwFile, (char *)"           %.11g %.11g\n", xl[i], yl[i]);
          lefwLines++;
        }
        encPrint(lefwFile, (char *)"           DO %d BY %d STEP %.11g %.11g ", numX, numY, spaceX, spaceY);
      } else {
        if (mask) {
          encPrint(lefwFile, (char *)"         PATH MASK %d ", mask);
        } else {
          encPrint(lefwFile, (char *)"         PATH ");
        }
        numItem = 0;
        for (i = 0; i < num_paths; i++) {
          if (numItem > 5) {
            encPrint(lefwFile, (char *)"\n");
            encPrint(lefwFile, (char *)"           %.11g %.11g ", xl[i], yl[i]);
            numItem = 0;
            lefwLines++;
          } else
            encPrint(lefwFile, (char *)"%.11g %.11g ", xl[i], yl[i]);
          numItem++;
        }
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      if (numX || numY || spaceX || spaceY) {
        if (mask) {
          fprintf(lefwFile, "         PATH MASK %d ITERATE ", mask);
        } else {
          fprintf(lefwFile, "         PATH ITERATE ");
        }
        for (i = 0; i < num_paths; i++) {
          if (i == 0)
            fprintf(lefwFile, "%.11g %.11g\n", xl[i], yl[i]);
          else
            fprintf(lefwFile, "           %.11g %.11g\n", xl[i], yl[i]);
          lefwLines++;
        }
        fprintf(lefwFile, "           DO %d BY %d STEP %.11g %.11g ", numX, numY, spaceX, spaceY);
      } else {
        if (mask) {
          fprintf(lefwFile, "         PATH MASK %d ", mask);
        } else {
          fprintf(lefwFile, "         PATH ");
        }
        numItem = 0;
        for (i = 0; i < num_paths; i++) {
          if (numItem > 5) {
            fprintf(lefwFile, "\n");
            fprintf(lefwFile, "           %.11g %.11g ", xl[i], yl[i]);
            numItem = 0;
            lefwLines++;
          } else
            fprintf(lefwFile, "%.11g %.11g ", xl[i], yl[i]);
          numItem++;
        }
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwMacroPinPortLayerRect(double xl1, double yl1, double xl2, double yl2, int numX,
                                int    numY,  // optional
                                double spaceX,
                                double spaceY,  // optional
                                int    mask) {     // optional
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPinPortLayer)
      return LEFW_BAD_ORDER;
    if (mask && versionNum < 5.8) {
      return LEFW_WRONG_VERSION;
    }
  
    if (!lefwValidateMaskNumber(mask)) {
      return LEFW_BAD_DATA;
    }
  
    if (lefwWriteEncrypt) {
      if (numX || numY || spaceX || spaceY) {
        if (mask) {
          encPrint(lefwFile, (char *)"            RECT MASK %d ITERATE %.11g %.11g %.11g %.11g ", mask, xl1, yl1, xl2, yl2);
        } else {
          encPrint(lefwFile, (char *)"            RECT ITERATE %.11g %.11g %.11g %.11g ", xl1, yl1, xl2, yl2);
        }
        encPrint(lefwFile, (char *)"DO %d BY %d STEP %.11g %.11g ", numX, numY, spaceX, spaceY);
      } else {
        if (mask) {
          encPrint(lefwFile, (char *)"            RECT MASK %d %.11g %.11g %.11g %.11g ", mask, xl1, yl1, xl2, yl2);
        } else {
          encPrint(lefwFile, (char *)"            RECT %.11g %.11g %.11g %.11g ", xl1, yl1, xl2, yl2);
        }
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      if (numX || numY || spaceX || spaceY) {
        if (mask) {
          fprintf(lefwFile, "            RECT MASK %d ITERATE %.11g %.11g %.11g %.11g ", mask, xl1, yl1, xl2, yl2);
        } else {
          fprintf(lefwFile, "            RECT ITERATE %.11g %.11g %.11g %.11g ", xl1, yl1, xl2, yl2);
        }
        fprintf(lefwFile, "DO %d BY %d STEP %.11g %.11g ", numX, numY, spaceX, spaceY);
      } else {
        if (mask) {
          fprintf(lefwFile, "            RECT MASK %d %.11g %.11g %.11g %.11g ", mask, xl1, yl1, xl2, yl2);
        } else {
          fprintf(lefwFile, "            RECT %.11g %.11g %.11g %.11g ", xl1, yl1, xl2, yl2);
        }
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwMacroPinPortLayerPolygon(int num_polys, double *xl, double *yl, int numX,
                                   int    numY,  // optional
                                   double spaceX,
                                   double spaceY,  // optional
                                   int    mask) {     // optional
    int i;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPinPortLayer)
      return LEFW_BAD_ORDER;
    if (num_polys < 4)
      return LEFW_BAD_DATA;  // at least 4 points
    if (mask && versionNum < 5.8) {
      return LEFW_WRONG_VERSION;
    }
  
    if (!lefwValidateMaskNumber(mask)) {
      return LEFW_BAD_DATA;
    }
  
    if (lefwWriteEncrypt) {
      if (numX || numY || spaceX || spaceY) {
        if (mask) {
          encPrint(lefwFile, (char *)"            POLYGON MASK %d ITERATE ", mask);
        } else {
          encPrint(lefwFile, (char *)"            POLYGON ITERATE ");
        }
        for (i = 0; i < num_polys; i++) {
          if (i == 0)
            encPrint(lefwFile, (char *)"%.11g %.11g\n", *xl++, *yl++);
          else
            encPrint(lefwFile, (char *)"               %.11g %.11g\n", *xl++, *yl++);
          lefwLines++;
        }
        encPrint(lefwFile, (char *)"               DO %d BY %d STEP %.11g %.11g ;\n", numX, numY, spaceX, spaceY);
      } else {
        if (mask) {
          encPrint(lefwFile, (char *)"            POLYGON MASK %d ", mask);
        } else {
          encPrint(lefwFile, (char *)"            POLYGON ");
        }
        for (i = 0; i < num_polys; i++) {
          if (i == 0)
            encPrint(lefwFile, (char *)"%.11g %.11g", *xl++, *yl++);
          else
            encPrint(lefwFile, (char *)"\n               %.11g %.11g", *xl++, *yl++);
          lefwLines++;
        }
        encPrint(lefwFile, (char *)" ;\n");
      }
    } else {
      if (numX || numY || spaceX || spaceY) {
        if (mask) {
          fprintf(lefwFile, "            POLYGON MASK %d ITERATE ", mask);
        } else {
          fprintf(lefwFile, "            POLYGON ITERATE ");
        }
        for (i = 0; i < num_polys; i++) {
          if (i == 0)
            fprintf(lefwFile, "%.11g %.11g\n", *xl++, *yl++);
          else
            fprintf(lefwFile, "               %.11g %.11g\n", *xl++, *yl++);
          lefwLines++;
        }
        fprintf(lefwFile, "               DO %d BY %d STEP %.11g %.11g ;\n", numX, numY, spaceX, spaceY);
      } else {
        if (mask) {
          fprintf(lefwFile, "            POLYGON MASK %d ", mask);
        } else {
          fprintf(lefwFile, "            POLYGON ");
        }
        for (i = 0; i < num_polys; i++) {
          if (i == 0)
            fprintf(lefwFile, "%.11g %.11g", *xl++, *yl++);
          else
            fprintf(lefwFile, "\n               %.11g %.11g", *xl++, *yl++);
          lefwLines++;
        }
        fprintf(lefwFile, " ;\n");
      }
    }
  
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwMacroPinPortVia(double xl, double yl, const char *viaName, int numX,
                          int    numY,  // optional
                          double spaceX,
                          double spaceY,  // optional
                          int    mask) {     // optional
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroPinPort)
      return LEFW_BAD_ORDER;
    if (!viaName || viaName == 0 || *viaName == 0)
      return LEFW_BAD_DATA;
    if (mask && versionNum < 5.8) {
      return LEFW_WRONG_VERSION;
    }
  
    if (!lefwValidateMaskNumber(mask)) {
      return LEFW_BAD_DATA;
    }
  
    if (lefwWriteEncrypt) {
      if (numX || numY || spaceX || spaceY) {
        if (mask) {
          encPrint(lefwFile, (char *)"            VIA ITERATE MASK %d %.11g %.11g %s ", mask, xl, yl, viaName);
        } else {
          encPrint(lefwFile, (char *)"            VIA ITERATE %.11g %.11g %s ", xl, yl, viaName);
        }
        encPrint(lefwFile, (char *)"DO %d BY %d STEP %.11g %.11g ", numX, numY, spaceX, spaceY);
      } else
        encPrint(lefwFile, (char *)"            VIA %.11g %.11g %s ", xl, yl, viaName);
      encPrint(lefwFile, (char *)";\n");
    } else {
      if (numX || numY || spaceX || spaceY) {
        if (mask) {
          fprintf(lefwFile, "            VIA ITERATE MASK %d %.11g %.11g %s ", mask, xl, yl, viaName);
        } else {
          fprintf(lefwFile, "            VIA ITERATE %.11g %.11g %s ", xl, yl, viaName);
        }
        fprintf(lefwFile, "DO %d BY %d STEP %.11g %.11g ", numX, numY, spaceX, spaceY);
      } else {
        if (mask) {
          fprintf(lefwFile, "            VIA MASK %d %.11g %.11g %s ", mask, xl, yl, viaName);
        } else {
          fprintf(lefwFile, "            VIA %.11g %.11g %s ", xl, yl, viaName);
        }
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwEndMacroPinPort() {
    if (!lefwIsMacroPinPort)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      END\n");
    else
      fprintf(lefwFile, "      END\n");
  
    lefwLines++;
    lefwIsMacroPinPort = 0;
    return LEFW_OK;
  }
  
  int lefwStartMacroObs() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (lefwIsMacroObs)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   OBS\n");
    else
      fprintf(lefwFile, "   OBS\n");
  
    lefwIsMacroObs = 1;
    lefwSpacingVal = 0;
    lefwWidthVal   = 0;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwMacroObsLayer(const char *layerName, double spacing) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroObs)
      return LEFW_BAD_ORDER;
    if (!layerName || layerName == 0 || *layerName == 0)
      return LEFW_BAD_DATA;
    if (lefwWidthVal)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      LAYER %s ", layerName);
      if (spacing)
        encPrint(lefwFile, (char *)"SPACING %.11g ", spacing);
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      LAYER %s ", layerName);
      if (spacing)
        fprintf(lefwFile, "SPACING %.11g ", spacing);
      fprintf(lefwFile, ";\n");
    }
    lefwLines++;
    lefwIsMacroObsLayer = 1;
    lefwSpacingVal      = 1;
    return LEFW_OK;
  }
  
  int lefwMacroObsDesignRuleWidth(const char *layerName, double width) {
    lefw54Num = LEFW_DESIGNRULEWIDTH;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroObs)
      return LEFW_BAD_ORDER;
    if (!layerName || layerName == 0 || *layerName == 0)
      return LEFW_BAD_DATA;
    if (lefwSpacingVal)
      return LEFW_BAD_DATA;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      LAYER %s ", layerName);
      if (width)
        encPrint(lefwFile, (char *)"DESIGNRULEWIDTH %.11g ", width);
      encPrint(lefwFile, (char *)";\n");
    } else {
      fprintf(lefwFile, "      LAYER %s ", layerName);
      if (width)
        fprintf(lefwFile, "DESIGNRULEWIDTH %.11g ", width);
      fprintf(lefwFile, ";\n");
    }
    lefwLines++;
    lefwIsMacroObsLayer = 1;
    lefwWidthVal        = 1;
    return LEFW_OK;
  }
  
  int lefwMacroExceptPGNet(const char *layerName) {
    lefw54Num = LEFW_DESIGNRULEWIDTH;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroObs)
      return LEFW_BAD_ORDER;
    if (!layerName || layerName == 0 || *layerName == 0)
      return LEFW_BAD_DATA;
    if (lefwSpacingVal)
      return LEFW_BAD_DATA;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      LAYER %s EXCEPTPGNET ;\n", layerName);
    else
      fprintf(lefwFile, "      LAYER %s EXCEPTPGNET ;\n", layerName);
    lefwLines++;
    lefwIsMacroObsLayer = 1;
    lefwWidthVal        = 1;
    return LEFW_OK;
  }
  
  int lefwMacroObsLayerWidth(double width) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroObsLayer)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      WIDTH %.11g ;\n", width);
    else
      fprintf(lefwFile, "      WIDTH %.11g ;\n", width);
    lefwLines++;
    lefwIsMacroObsLayer = 1;
    return LEFW_OK;
  }
  
  int lefwMacroObsLayerPath(int num_paths, double *xl, double *yl, int numX,
                            int    numY,  // optional
                            double spaceX,
                            double spaceY,  // optional
                            int    mask) {     // optional
    int i, numItem;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroObsLayer)
      return LEFW_BAD_ORDER;
    if (mask && versionNum < 5.8) {
      return LEFW_WRONG_VERSION;
    }
  
    if (!lefwValidateMaskNumber(mask)) {
      return LEFW_BAD_DATA;
    }
  
    if (lefwWriteEncrypt) {
      if (numX || numY || spaceX || spaceY) {
        if (mask) {
          encPrint(lefwFile, (char *)"         PATH MASK %d ITERATE ", mask);
        } else {
          encPrint(lefwFile, (char *)"         PATH ITERATE ");
        }
        for (i = 0; i < num_paths; i++) {
          if (i == 0)
            encPrint(lefwFile, (char *)"%.11g %.11g\n", *xl++, *yl++);
          else
            encPrint(lefwFile, (char *)"            %.11g %.11g\n", *xl++, *yl++);
          lefwLines++;
        }
        encPrint(lefwFile, (char *)"           DO %d BY %d STEP %.11g %.11g ", numX, numY, spaceX, spaceY);
      } else {
        if (mask) {
          encPrint(lefwFile, (char *)"         PATH MASK %d ", mask);
        } else {
          encPrint(lefwFile, (char *)"         PATH ");
        }
        numItem = 0;
        for (i = 0; i < num_paths; i++) {
          if (numItem > 5) {
            encPrint(lefwFile, (char *)"\n");
            encPrint(lefwFile, (char *)"         %.11g %.11g ", xl[i], yl[i]);
            numItem = 0;
            lefwLines++;
          } else
            encPrint(lefwFile, (char *)"%.11g %.11g ", xl[i], yl[i]);
          numItem++;
        }
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      if (numX || numY || spaceX || spaceY) {
        if (mask) {
          fprintf(lefwFile, "         PATH MASK %d ITERATE ", mask);
        } else {
          fprintf(lefwFile, "         PATH ITERATE ");
        }
        for (i = 0; i < num_paths; i++) {
          if (i == 0)
            fprintf(lefwFile, "%.11g %.11g\n", *xl++, *yl++);
          else
            fprintf(lefwFile, "            %.11g %.11g\n", *xl++, *yl++);
          lefwLines++;
        }
        fprintf(lefwFile, "           DO %d BY %d STEP %.11g %.11g ", numX, numY, spaceX, spaceY);
      } else {
        if (mask) {
          fprintf(lefwFile, "         PATH MASK %d ", mask);
        } else {
          fprintf(lefwFile, "         PATH ");
        }
        numItem = 0;
        for (i = 0; i < num_paths; i++) {
          if (numItem > 5) {
            fprintf(lefwFile, "\n");
            fprintf(lefwFile, "         %.11g %.11g ", xl[i], yl[i]);
            numItem = 0;
            lefwLines++;
          } else
            fprintf(lefwFile, "%.11g %.11g ", xl[i], yl[i]);
          numItem++;
        }
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwMacroObsLayerRect(double xl1, double yl1, double xl2, double yl2, int numX,
                            int    numY,  // optional
                            double spaceX,
                            double spaceY,  // optional
                            int    mask) {     // optional
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroObsLayer)
      return LEFW_BAD_ORDER;
    if (mask && versionNum < 5.8) {
      return LEFW_WRONG_VERSION;
    }
  
    if (!lefwValidateMaskNumber(mask)) {
      return LEFW_BAD_DATA;
    }
  
    if (lefwWriteEncrypt) {
      if (numX || numY || spaceX || spaceY) {
        if (mask) {
          encPrint(lefwFile, (char *)"         RECT MASK %d ITERATE %.11g %.11g %.11g %.11g ", mask, xl1, yl1, xl2, yl2);
        } else {
          encPrint(lefwFile, (char *)"         RECT ITERATE %.11g %.11g %.11g %.11g ", xl1, yl1, xl2, yl2);
        }
        encPrint(lefwFile, (char *)"DO %d BY %d STEP %.11g %.11g ", numX, numY, spaceX, spaceY);
      } else {
        if (mask) {
          encPrint(lefwFile, (char *)"         RECT MASK %d %.11g %.11g %.11g %.11g ", mask, xl1, yl1, xl2, yl2);
        } else {
          encPrint(lefwFile, (char *)"         RECT %.11g %.11g %.11g %.11g ", xl1, yl1, xl2, yl2);
        }
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      if (numX || numY || spaceX || spaceY) {
        if (mask) {
          fprintf(lefwFile, "         RECT MASK %d ITERATE %.11g %.11g %.11g %.11g ", mask, xl1, yl1, xl2, yl2);
        } else {
          fprintf(lefwFile, "         RECT ITERATE %.11g %.11g %.11g %.11g ", xl1, yl1, xl2, yl2);
        }
        fprintf(lefwFile, "DO %d BY %d STEP %.11g %.11g ", numX, numY, spaceX, spaceY);
      } else {
        if (mask) {
          fprintf(lefwFile, "         RECT MASK %d %.11g %.11g %.11g %.11g ", mask, xl1, yl1, xl2, yl2);
        } else {
          fprintf(lefwFile, "         RECT %.11g %.11g %.11g %.11g ", xl1, yl1, xl2, yl2);
        }
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwMacroObsLayerPolygon(int num_polys, double *xl, double *yl, int numX,
                               int    numY,  // optional
                               double spaceX,
                               double spaceY,  // optional
                               int    mask) {     // optional
    int i;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroObsLayer)
      return LEFW_BAD_ORDER;
    if (num_polys < 4)
      return LEFW_BAD_DATA;  // at least 4 points
    if (mask && versionNum < 5.8) {
      return LEFW_WRONG_VERSION;
    }
  
    if (!lefwValidateMaskNumber(mask)) {
      return LEFW_BAD_DATA;
    }
  
    if (lefwWriteEncrypt) {
      if (numX || numY || spaceX || spaceY) {
        if (mask) {
          encPrint(lefwFile, (char *)"         POLYGON MASK %d ITERATE ", mask);
        } else {
          encPrint(lefwFile, (char *)"         POLYGON ITERATE ");
        }
        for (i = 0; i < num_polys; i++) {
          if (i == 0)
            encPrint(lefwFile, (char *)"%.11g %.11g\n", *xl++, *yl++);
          else
            encPrint(lefwFile, (char *)"           %.11g %.11g\n", *xl++, *yl++);
          lefwLines++;
        }
        encPrint(lefwFile, (char *)"           DO %d BY %d STEP %.11g %.11g ;", numX, numY, spaceX, spaceY);
      } else {
        if (mask) {
          encPrint(lefwFile, (char *)"         POLYGON MASK %d ", mask);
        } else {
          encPrint(lefwFile, (char *)"         POLYGON ");
        }
        for (i = 0; i < num_polys; i++) {
          if (i == 0)
            encPrint(lefwFile, (char *)"%.11g %.11g", *xl++, *yl++);
          else
            encPrint(lefwFile, (char *)"\n           %.11g %.11g", *xl++, *yl++);
          lefwLines++;
        }
        encPrint(lefwFile, (char *)" ;\n");
      }
    } else {
      if (numX || numY || spaceX || spaceY) {
        if (mask) {
          fprintf(lefwFile, "         POLYGON MASK %d ITERATE ", mask);
        } else {
          fprintf(lefwFile, "         POLYGON ITERATE ");
        }
        for (i = 0; i < num_polys; i++) {
          if (i == 0)
            fprintf(lefwFile, "%.11g %.11g\n", *xl++, *yl++);
          else
            fprintf(lefwFile, "           %.11g %.11g\n", *xl++, *yl++);
          lefwLines++;
        }
        fprintf(lefwFile, "           DO %d BY %d STEP %.11g %.11g ;", numX, numY, spaceX, spaceY);
      } else {
        if (mask) {
          fprintf(lefwFile, "         POLYGON MASK %d ", mask);
        } else {
          fprintf(lefwFile, "         POLYGON ");
        }
        for (i = 0; i < num_polys; i++) {
          if (i == 0)
            fprintf(lefwFile, "%.11g %.11g", *xl++, *yl++);
          else
            fprintf(lefwFile, "\n           %.11g %.11g", *xl++, *yl++);
          lefwLines++;
        }
        fprintf(lefwFile, " ;\n");
      }
    }
  
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwMacroObsVia(double xl, double yl, const char *viaName, int numX,
                      int    numY,  // optional
                      double spaceX,
                      double spaceY,  // optional
                      int    mask) {     // optional
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroObs)
      return LEFW_BAD_ORDER;
    if (!viaName || viaName == 0 || *viaName == 0)
      return LEFW_BAD_DATA;
    if (mask && versionNum < 5.8) {
      return LEFW_WRONG_VERSION;
    }
  
    if (!lefwValidateMaskNumber(mask)) {
      return LEFW_BAD_DATA;
    }
  
    if (lefwWriteEncrypt) {
      if (numX || numY || spaceX || spaceY) {
        if (mask) {
          encPrint(lefwFile, (char *)"      VIA ITERATE MASK %d %.11g %.11g %s ", mask, xl, yl, viaName);
        } else {
          encPrint(lefwFile, (char *)"      VIA ITERATE %.11g %.11g %s ", xl, yl, viaName);
        }
        encPrint(lefwFile, (char *)"DO %d BY %d STEP %.11g %.11g ", numX, numY, spaceX, spaceY);
      } else {
        if (mask) {
          encPrint(lefwFile, (char *)"      VIA MASK %d %.11g %.11g %s ", mask, xl, yl, viaName);
        } else {
          encPrint(lefwFile, (char *)"      VIA %.11g %.11g %s ", xl, yl, viaName);
        }
      }
      encPrint(lefwFile, (char *)";\n");
    } else {
      if (numX || numY || spaceX || spaceY) {
        if (mask) {
          fprintf(lefwFile, "      VIA ITERATE MASK %d %.11g %.11g %s ", mask, xl, yl, viaName);
        } else {
          fprintf(lefwFile, "      VIA ITERATE %.11g %.11g %s ", xl, yl, viaName);
        }
        fprintf(lefwFile, "DO %d BY %d STEP %.11g %.11g ", numX, numY, spaceX, spaceY);
      } else {
        if (mask) {
          fprintf(lefwFile, "      VIA MASK %d %.11g %.11g %s ", mask, xl, yl, viaName);
        } else {
          fprintf(lefwFile, "      VIA %.11g %.11g %s ", xl, yl, viaName);
        }
      }
      fprintf(lefwFile, ";\n");
    }
  
    lefwLines++;
    lefwIsMacroObsLayer = 0;
    return LEFW_OK;
  }
  
  int lefwEndMacroObs() {
    if (!lefwIsMacroObs)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   END\n");
    else
      fprintf(lefwFile, "   END\n");
  
    lefwLines++;
    lefwIsMacroObs = 0;
    return LEFW_OK;
  }
  
  int lefwStartMacroTiming() {
    lefwObsoleteNum = LEFW_MACRO_TIMING;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_MACRO_START && lefwState != LEFW_MACRO)
      return LEFW_BAD_ORDER;
    if (lefwIsMacroTiming)
      return LEFW_BAD_ORDER;
    if (versionNum >= 5.4)
      return LEFW_OBSOLETE;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   TIMING\n");
    else
      fprintf(lefwFile, "   TIMING\n");
  
    lefwIsMacroTiming      = 1;
    lefwIsMacroTimingModel = 0;
    lefwLines++;
    return LEFW_OK;
  }
  
  // Obsolete in 5.4
  int lefwMacroTimingPin(const char *fromPin, const char *toPin) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroTiming)
      return LEFW_BAD_ORDER;
    if (fromPin) {
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)"      FROMPIN %s ;\n", fromPin);
      else
        fprintf(lefwFile, "      FROMPIN %s ;\n", fromPin);
      lefwLines++;
    }
    if (toPin) {
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)"      TOPIN %s ;\n", toPin);
      else
        fprintf(lefwFile, "      TOPIN %s ;\n", toPin);
      lefwLines++;
    }
    return LEFW_OK;
  }
  
  // Obsolete in 5.4
  int lefwMacroTimingIntrinsic(const char *riseFall, double min, double max, double slewT1,
                               double slewT1Min,  // optional
                               double slewT1Max,
                               double slewT2,  // optional
                               double slewT2Min,
                               double slewT2Max,  // optional
                               double slewT3,     // optional
                               double varMin, double varMax) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroTiming)
      return LEFW_BAD_ORDER;
    if (strcmp(riseFall, "RISE") && strcmp(riseFall, "FALL"))
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt) {
      encPrint(lefwFile, (char *)"      %s INTRINSIC %.11g %.11g ", riseFall, min, max);
      if (slewT1 || slewT1Min || slewT1Max || slewT2) {
        encPrint(lefwFile, (char *)"%.11g %.11g %.11g %.11g ", slewT1, slewT1Min, slewT1Max, slewT2);
        if (slewT2Min || slewT2Max || slewT3)
          encPrint(lefwFile, (char *)"%.11g %.11g %.11g \n", slewT2Min, slewT2Max, slewT3);
      } else if (slewT2Min || slewT2Max || slewT3)
        return LEFW_BAD_DATA;  // slewT2Min... has to be inside of slewT1...
      encPrint(lefwFile, (char *)"         VARIABLE %.11g %.11g ;\n", varMin, varMax);
    } else {
      fprintf(lefwFile, "      %s INTRINSIC %.11g %.11g ", riseFall, min, max);
      if (slewT1 || slewT1Min || slewT1Max || slewT2) {
        fprintf(lefwFile, "%.11g %.11g %.11g %.11g ", slewT1, slewT1Min, slewT1Max, slewT2);
        if (slewT2Min || slewT2Max || slewT3)
          fprintf(lefwFile, "%.11g %.11g %.11g \n", slewT2Min, slewT2Max, slewT3);
      } else if (slewT2Min || slewT2Max || slewT3)
        return LEFW_BAD_DATA;  // slewT2Min... has to be inside of slewT1...
      fprintf(lefwFile, "         VARIABLE %.11g %.11g ;\n", varMin, varMax);
    }
    lefwLines++;
    return LEFW_OK;
  }
  
  // Obsolete in 5.4
  int lefwMacroTimingRisers(double min, double max) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroTiming)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      RISERS %.11g %.11g ;\n", min, max);
    else
      fprintf(lefwFile, "      RISERS %.11g %.11g ;\n", min, max);
    lefwLines++;
    return LEFW_OK;
  }
  
  // Obsolete in 5.4
  int lefwMacroTimingFallrs(double min, double max) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroTiming)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      FALLRS %.11g %.11g ;\n", min, max);
    else
      fprintf(lefwFile, "      FALLRS %.11g %.11g ;\n", min, max);
    lefwLines++;
    return LEFW_OK;
  }
  
  // Obsolete in 5.4
  int lefwMacroTimingRisecs(double min, double max) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroTiming)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      RISECS %.11g %.11g ;\n", min, max);
    else
      fprintf(lefwFile, "      RISECS %.11g %.11g ;\n", min, max);
    lefwLines++;
    return LEFW_OK;
  }
  
  // Obsolete in 5.4
  int lefwMacroTimingFallcs(double min, double max) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroTiming)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      FALLCS %.11g %.11g ;\n", min, max);
    else
      fprintf(lefwFile, "      FALLCS %.11g %.11g ;\n", min, max);
    lefwLines++;
    return LEFW_OK;
  }
  
  // Obsolete in 5.4
  int lefwMacroTimingRisesatt1(double min, double max) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroTiming)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      RISESATT1 %.11g %.11g ;\n", min, max);
    else
      fprintf(lefwFile, "      RISESATT1 %.11g %.11g ;\n", min, max);
    lefwLines++;
    return LEFW_OK;
  }
  
  // Obsolete in 5.4
  int lefwMacroTimingFallsatt1(double min, double max) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroTiming)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      FALLSATT1 %.11g %.11g ;\n", min, max);
    else
      fprintf(lefwFile, "      FALLSATT1 %.11g %.11g ;\n", min, max);
    lefwLines++;
    return LEFW_OK;
  }
  
  // Obsolete in 5.4
  int lefwMacroTimingRiset0(double min, double max) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroTiming)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      RISET0 %.11g %.11g ;\n", min, max);
    else
      fprintf(lefwFile, "      RISET0 %.11g %.11g ;\n", min, max);
    lefwLines++;
    return LEFW_OK;
  }
  
  // Obsolete in 5.4
  int lefwMacroTimingFallt0(double min, double max) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroTiming)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      FALLT0 %.11g %.11g ;\n", min, max);
    else
      fprintf(lefwFile, "      FALLT0 %.11g %.11g ;\n", min, max);
    lefwLines++;
    return LEFW_OK;
  }
  
  // Obsolete in 5.4
  int lefwMacroTimingUnateness(const char *unateness) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (!lefwIsMacroTiming)
      return LEFW_BAD_ORDER;
    if (strcmp(unateness, "INVERT") && strcmp(unateness, "NONINVERT") && strcmp(unateness, "NONUNATE"))
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"      UNATENESS %s ; \n", unateness);
    else
      fprintf(lefwFile, "      UNATENESS %s ; \n", unateness);
    lefwLines++;
    return LEFW_OK;
  }
  
  // Obsolete in 5.4
  int lefwEndMacroTiming() {
    if (!lefwIsMacroTiming)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   END TIMING\n\n");
    else
      fprintf(lefwFile, "   END TIMING\n\n");
  
    lefwLines++;
    lefwIsMacroTiming = 0;
    return LEFW_OK;
  }
  
  int lefwAntenna(const char *type, double value) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (!type || type == 0 || *type == 0)
      return LEFW_BAD_DATA;
    if (strcmp(type, "INPUTPINANTENNASIZE") && strcmp(type, "OUTPUTPINANTENNASIZE") && strcmp(type, "INOUTPINANTENNASIZE"))
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"%s %.11g ;\n", type, value);
    else
      fprintf(lefwFile, "%s %.11g ;\n", type, value);
  
    lefwLines++;
    lefwSynArray[LEFW_ANTENNASIZE] = 1;
    return LEFW_OK;
  }
  
  int lefwAntennaInputGateArea(double inputGateArea) {
    lefw54Num = LEFW_ANTENNAINPUTGATEAREA;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (lefwSynArray[LEFW_ANTENNAINPUTGATEAREA])
      return LEFW_ALREADY_DEFINED;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"ANTENNAINPUTGATEAREA %.11g ;\n", inputGateArea);
    else
      fprintf(lefwFile, "ANTENNAINPUTGATEAREA %.11g ;\n", inputGateArea);
    lefwLines++;
    lefwSynArray[LEFW_ANTENNAINPUTGATEAREA] = 1;
    return LEFW_OK;
  }
  
  int lefwAntennaInOutDiffArea(double inOutDiffArea) {
    lefw54Num = LEFW_ANTENNAINOUTDIFFAREA;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (lefwSynArray[LEFW_ANTENNAINOUTDIFFAREA])
      return LEFW_ALREADY_DEFINED;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"ANTENNAINOUTDIFFAREA %.11g ;\n", inOutDiffArea);
    else
      fprintf(lefwFile, "ANTENNAINOUTDIFFAREA %.11g ;\n", inOutDiffArea);
    lefwLines++;
    lefwSynArray[LEFW_ANTENNAINOUTDIFFAREA] = 1;
    return LEFW_OK;
  }
  
  int lefwAntennaOutputDiffArea(double outputDiffArea) {
    lefw54Num = LEFW_ANTENNAOUTPUTDIFFAREA;
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_INIT && lefwState < LEFW_END)
      return LEFW_BAD_ORDER;  // not of the ENDs
    if (lefwSynArray[LEFW_ANTENNAOUTPUTDIFFAREA])
      return LEFW_ALREADY_DEFINED;
    if (versionNum < 5.4)
      return LEFW_WRONG_VERSION;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"ANTENNAOUTPUTDIFFAREA %.11g ;\n", outputDiffArea);
    else
      fprintf(lefwFile, "ANTENNAOUTPUTDIFFAREA %.11g ;\n", outputDiffArea);
    lefwLines++;
    lefwSynArray[LEFW_ANTENNAOUTPUTDIFFAREA] = 1;
    return LEFW_OK;
  }
  
  int lefwStartBeginext(const char *name) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState == LEFW_BEGINEXT_START || lefwState == LEFW_BEGINEXT)
      return LEFW_BAD_ORDER;
    if (!name || name == 0 || *name == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"BEGINEXT \"%s\"", name);
    // \n will be added later
    else
      fprintf(lefwFile, "BEGINEXT \"%s\"", name);
  
    lefwState = LEFW_BEGINEXT_START;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwBeginextCreator(const char *creatorName) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_BEGINEXT_START && lefwState != LEFW_BEGINEXT)
      return LEFW_BAD_ORDER;
    if (!creatorName || creatorName == 0 || *creatorName == 0)
      return LEFW_BAD_DATA;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"\n   CREATOR \"%s\"", creatorName);
    else
      fprintf(lefwFile, "\n   CREATOR \"%s\"", creatorName);
  
    lefwState = LEFW_BEGINEXT;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwBeginextDate() {
    time_t todayTime;
    char * rettime;
  
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_BEGINEXT_START && lefwState != LEFW_BEGINEXT)
      return LEFW_BAD_ORDER;
  
    todayTime                    = time(NULL);         // time in UTC
    rettime                      = ctime(&todayTime);  // convert to string
    rettime[strlen(rettime) - 1] = '\0';               // replace \n with \0
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"\n   DATE \"%s\"", rettime);
    else
      fprintf(lefwFile, "\n   DATE \"%s\"", rettime);
  
    lefwState = LEFW_BEGINEXT;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwBeginextRevision(int vers1, int vers2) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_BEGINEXT_START && lefwState != LEFW_BEGINEXT)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"\n   REVISION %d.%d", vers1, vers2);
    else
      fprintf(lefwFile, "\n   REVISION %d.%d", vers1, vers2);
  
    lefwState = LEFW_BEGINEXT;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwBeginextSyntax(const char *title, const char *string) {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_BEGINEXT_START && lefwState != LEFW_BEGINEXT)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"\n   - %s %s", title, string);
    else
      fprintf(lefwFile, "\n   - %s %s", title, string);
  
    lefwState = LEFW_BEGINEXT;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwEndBeginext() {
    if (!lefwFile)
      return LEFW_UNINITIALIZED;
    if (!lefwDidInit)
      return LEFW_BAD_ORDER;
    if (lefwState != LEFW_BEGINEXT_START && lefwState != LEFW_BEGINEXT)
      return LEFW_BAD_ORDER;
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)";\nENDEXT\n\n");
    else
      fprintf(lefwFile, ";\nENDEXT\n\n");
  
    lefwState = LEFW_BEGINEXT_END;
    lefwLines++;
    return LEFW_OK;
  }
  
  int lefwCurrentLineNumber() { return lefwLines; }
  
  void lefwPrintError(int status) {
    switch (status) {
      case LEFW_OK:
        if (lefwWriteEncrypt)
          encPrint(lefwFile, (char *)"No Error.\n");
        else
          fprintf(lefwFile, "No Error.\n");
        break;
      case LEFW_UNINITIALIZED:
        if (lefwWriteEncrypt)
          encPrint(lefwFile, (char *)"Need to call lefwInit first.\n");
        else
          fprintf(lefwFile, "Need to call lefwInit first.\n");
        break;
      case LEFW_BAD_ORDER:
        if (lefwWriteEncrypt)
          encPrint(lefwFile, (char *)"Incorrect order of data.\n");
        else
          fprintf(lefwFile, "Incorrect order of data.\n");
        break;
      case LEFW_BAD_DATA:
        if (lefwWriteEncrypt)
          encPrint(lefwFile, (char *)"Invalid data.\n");
        else
          fprintf(lefwFile, "Invalid data.\n");
        break;
      case LEFW_ALREADY_DEFINED:
        if (lefwWriteEncrypt)
          encPrint(lefwFile, (char *)"Section is allowed to define only once.\n");
        else
          fprintf(lefwFile, "Section is allowed to define only once.\n");
        break;
      case LEFW_WRONG_VERSION:
        if (lefwWriteEncrypt)
          encPrint(lefwFile, (char *)"Version number is set before 5.4, API: %s is for 5.4.\n", lefwStateStr[lefw54Num]);
        else
          fprintf(lefwFile, "Version number is set before 5.4, but 5.4, API: %s is for 5.4.\n", lefwStateStr[lefw54Num]);
        break;
      case LEFW_MIX_VERSION_DATA:
        if (lefwWriteEncrypt)
          encPrint(lefwFile, (char *)"You have made both 5.4 & pre 5.4 Antenna API called, which is invalid.\n");
  
        else
          fprintf(lefwFile, "You have made both 5.4 & pre 5.4 Antenna API called, which is invalid.\n");
        break;
      case LEFW_OBSOLETE:
        if (lefwWriteEncrypt)
          encPrint(lefwFile, (char *)"%s is no longer valid in %g.\n", lefwStateStr[lefwObsoleteNum], versionNum);
  
        else
          fprintf(lefwFile, "%s is no longer valid in %g.\n", lefwStateStr[lefwObsoleteNum], versionNum);
    }
    return;
  }
  
  void lefwAddComment(const char *comment) {
    if (comment) {
      if (lefwWriteEncrypt)
        encPrint(lefwFile, (char *)"# %s\n", comment);
      else
        fprintf(lefwFile, "# %s\n", comment);
    }
    return;
  }
  
  void lefwAddIndent() {
    if (lefwWriteEncrypt)
      encPrint(lefwFile, (char *)"   ");
    else
      fprintf(lefwFile, "   ");
    return;
  }
  
  // ***************************
  //   Questions:
  // - Is only one row rule allowed
  // - Is only one tracks rule allowed
  // - In the die area is a zero area allowed? overlaps?
  // - What type of checking is needed for the rows and tracks do loop?
  // - Can you have a default prop with a number AND a range?
  // - What is the pin properties section mentioned in the 5.1 spec?
  // *****************************
  
  END_LEFDEF_PARSER_NAMESPACE
  