Home > Community > Forums > PCB SKILL > printf() as first line and number formatting

Email

* Required Fields

Recipients email * (separate multiple addresses with commas)

Your name *

Your email *

Message *

Contact Us

* Required Fields
First Name *

Last Name *

Email *

Company / Institution *

Comments: *

 printf() as first line and number formatting 

Last post Mon, Jun 22 2009 9:54 AM by skillUser. 14 replies.
Started by EvanShultz 20 May 2009 10:45 AM. Topic has 14 replies and 6113 views
Page 1 of 1 (15 items)
Sort Posts:
  • Wed, May 20 2009 10:45 AM

    printf() as first line and number formatting Reply

    OK, here's a weird one for you. I want to print some information for the user into the Command window before I do anything else. So, I figured why not make a printf() statement the very first line of code? I suppose it should work - George does it on lines 25-35 of tekTechFileXML.il (from SourceLink). But for me, nothing is printed in the Command window. If I move the exact same statement as the first line of the procedure(), the text is printed to the Command window.

    So what's my problem? Well, farther down in the procedure() a subroutine is called which uses axlEnterPath(). And the "Enter first point" prompt from axlEnterPath() comes BEFORE my printf() text, even though the printf() comes first in the code. My mind is boggled. I changed the prompt for axlEnterPath so I know it is this SKILL function that is creating the prompt which is jumping ahead of my printf() text.

    Any ideas why this SKILL function can't wait it's turn? Or, better yet, how can I get the string in a printf() statement to show in the Command window if the printf() statement is the very first line of the SKILL routine?

     

     Secondly, I want to print out a table of information which may be integers or floating point numbers. How can I do this while keeping the table nicely lined up? Here is what I've found:

    %-10n - displays both number types, but pads with zeros for floating point numbers

    %-10g or %g - barfs on integers

    %-10L or %L - displays both number types, no padding zeros for fp, but ignores [width] field (as per page 170 of sklangref.pdf)

    So, what options do I have? I want similar to %-10n output, but without zero padding. %-10g would seem to be the right choice. I've used %g in other SKILL programs and it gracefully handled both integer and fp numbers - any ideas why it isn't with integers for me now?

    • Post Points: 20
  • Wed, May 20 2009 11:23 AM

    RE: printf() as first line and number formatting Reply
    Evan,

    The printf function is buffered.  Try using axlMsgPut.

    Regards,
    Charlie
    Charlie Davies
    • Post Points: 20
  • Wed, May 20 2009 4:42 PM

    Re: RE: printf() as first line and number formatting Reply

     Hi Charlie,

    Hmm, axlMsgPut still doesn't print if it's the first line, but it does print before axlEnterPath (when printf doesn't). So I'm satisfied. So is axlMsgPut best suited for displaying in the Command window and printf is best used for anything else (external file, buffer, etc)? Thanks!

     

    For my second issue, %g doesn't work in the other code I was referring to - it barfs on integers there too. I don't know what I was thinking. So, how can I place either integers or fp numbers in a certain width of field without having zeros padded?

    • Post Points: 20
  • Thu, May 21 2009 6:47 AM

    RE: RE: printf() as first line and number formatting Reply
    Evan,

    The only way I know to control formatting of mix types (integers and floats) in the same column would require you to preprocess the list of items, determine their values (character width), then dynamically create a formatted print statement suitable for what you’re trying to print.  Just to be clear I assume you want to print an integer as 1000 and not 1000.00.  Remember you can always turn an integer into a float (float function).

    Regards,
    Charlie
    Charlie Davies
    • Post Points: 20
  • Thu, May 21 2009 11:57 AM

    Re: RE: RE: printf() as first line and number formatting Reply

     Hi Charlie,

    You're correct, I wanted to print floats with only sig digs, and integers without anything the decimal or anything to the right of the decimal.

    Another smart guy out there pointed me toward using sprintf to assign the number to a string. That did it.

    • Post Points: 5
  • Wed, Jun 3 2009 6:19 PM

    Re: RE: RE: printf() as first line and number formatting Reply

     Not bring able to figure out how to format numbers like I want is starting to pile up on me and really trip me up. Consider these following 3 examples where I am currently stuck:

     

     Example 1 (the situation I've been describing in this thread):

    I am printing a report of component heights (reading PACKAGE_HEIGHT_MAX). As the components could be built in various units, and I want to convert to a single unit system (in my case MILS), I will end up with heights in various formats. Footprints built in MILS will likely be integers, but footprints built in MM will almost certainly be floating point numbers, as will footprints built in INCHES (for example, 2 INCHES = 2.000 MILS).

    To make the report much cleaner, I'd like footprints built in MILS to appear as integers. Footprints in MM and INCHES will almost certainly be fp numbers, but I'd prefer not to have trailing zeros.

    Question: How can I take a variable that is either an integer or fp number and format it without any trailing zeros so it can be printed as a number?

     

    Example 2:

    I want to accept user input and print it back to the user. As the design could be done in MILS, MM, or INCHES, the value the user inputs could be an integer or fp.

     Furthermore, I when I print the input back to the user, I want to append the units. So I need to take the number (either integer or fp) and make it a string then append the units. Now, I can use sprintf to make the number a string, and strcat to tie the number and units together, if I could just get the number properly formatted. It looks silly when the user puts in "2" (for example, in INCHES) and gets back "2.000 INCHES". If I was the user, I'd expect "2 INCHES". Similarly, if the user puts in "25" in MILS, you don't want to get back "25.000 MILS" since the trailing zeros are so small they're generally irrelevant.

    Question: How can I accept user input that is either integer or fp, and get that into a string without any trailing zeros (note similarity to above)?

     

    Example 3:

    I am creating a report in which one column is a property that is defined by the footprint symbol, but which is brought from the schematic ("Create user-defined properties" must be checked in the Export Physical form to annotate this property to Allegro). This property, the distance between through holes, is not present on SMT or irrelevant parts (property is "nil") and the property is "NA" for through hole parts where the pad spacing doesn't matter. Where pad spacing does matter, it is a fp number (for example, ".200" in MILS). I am using Extracta to get this property into my SKILL routine and then nth(...) to pull out the desired value from the Extracta output file.

      So, when the report is printed I am using "%L" format specification to be able to print either "nil", "NA", or a fp number without any errors but I am having problems with the resulting data. When the property doesn't exist, I get "nil" without quotes. When the property value is "NA" (without quotes), I get "NA" with quotes, which I assume is because this is a two-letter string. And if there is a number, I get the number surrounded by quotes.

    The program that needs this report cannot accept the quotes, so I must first remove the quotes. But how? Also, I'd prefer to have nothing in the report column if the property doesn't exist (or if it's "NA"), and (ideally) the only condition that would place something in this column would be if there is a value for this property that is not "NA" (without quotes). I can visualize how to do this, but I can't seem to figure out the right way to make it happen. I am able to detect "NA" as the value, but I'm not able to change it to "nil". I get a "left hand assignment error" when I try to set the nth(...) variable equal to "" (doube quotes) or "nil".

    Question: How can I accept a variable with a value of nothing (nil), a string, or a fp number, and print the variable without any errors? Bonus points if I can wipe out the value of the variable (make it nil) if it meets my criteria.

     

    Summary:

    Wow, I am long winded! Thank you if you could trudge through all that. I'm sure it's a bit harder to figure out without seeing the code, but I have to believe this is a fairly common problem. Ever since the first programs were written, I can imagine similar situations. There has to be a way  to achieve the formatting I desire or else programs I regularly use wouldn't display numbers the way they do. I know this type of formatting can be done.

    So, in short, if I have a variable that is an integer or fp number, how can I print it without trailing zeros?

    The second part of the question is similar to the first: if the variable may not have any value, or might be a string, or might be a fp number, how can I accept any of those and print out (optionally discarding strings and nil values) only the fp number, so I get nothing if the value of the variable is nothing?

    • Post Points: 20
  • Wed, Jun 3 2009 6:54 PM

    • eDave
    • Top 10 Contributor
    • Joined on Sun, Jul 13 2008
    • Christchurch, 00-NZ
    • Posts 718
    • Points 15,570
    Re: RE: RE: printf() as first line and number formatting Reply

    Hi Evan,

     There are plenty of ways to achieve this but these might give you some ideas:

    Eg.1: sprintf(nil, if(integerp(n), "%d", "%2.3f") n)

    Eg. 2: axlMKSStr2UU(sprintf(nil, "%n", readstring(sprintf(nil, "%n", value))))

    Eg. 3: if(value then value = readstring(value), axlMKSStr2UU(sprintf(nil, cond((stringp(value), value)(integerp(value), "%d"), (floatp(value), "%2.3f")) value)) else "")

     

     

    Dave Elder, Tait Communications
    • Post Points: 20
  • Fri, Jun 5 2009 4:11 AM

    • Ejlersen
    • Top 10 Contributor
    • Joined on Mon, Jul 28 2008
    • Aalborg, Copenhagen
    • Posts 556
    • Points 9,795
    Re: RE: RE: printf() as first line and number formatting Reply

    Hi

    As you point out, there are plenty of ways. I've used sprintf a number of times to create the formatting string. You can then just wrap this sprintf command into case or if/then constructs depending on what you're looking at. You just have to keep you head cold when writing the formatting string, it can get complex.

    example: (taken from a pick and place output utility that I've made)

    pn_length > 1 if partnumber is defined for part

    package_length is the length of the package symbol name (strlen)

    value_length is the length of the component value (strlen)

      if( pn_length > 1 then
       sprintf(pp_header "%s%d%s%d%s%d%s" "%-7s %-8s %-8s %-8.3f %-" (package_length +2) "s %-" (value_length +2) "s %-" (pn_length+2) "s\n")
      else
       sprintf(pp_header "%s%d%s%d%s%s" "%-7s %-8s %-8s %-8.3f %-" (package_length +2) "s %-" (value_length +2) "s" "\n")
      )

    then just use the fprintf or printf with the formatting header

         if( pn_length > 1 then
          fprintf(sm_top, pp_header, c_refdes, x_coor, y_coor, c_rotation, c_psm, c_value, c_pn)
         else
          fprintf(sm_top, pp_header, c_refdes, x_coor, y_coor, c_rotation, c_psm, c_value)
         )

    c_refdes=reference designator, x_coor is x coordinate, y_coor is y coordinate, c_rotation is the rotation, c_psm is the package symbol name, c_value is the component value and c_pn is the component partnumber

    Best regards

    Ole 

     

    Hope this helps?

     

    Best regards Ole
    • Post Points: 20
  • Wed, Jun 10 2009 5:34 PM

    Re: RE: RE: printf() as first line and number formatting Reply

     Hi Dave and Ole,

     Thank you very much! I am getting the formatting I desire now! I knew it could be done and you two showed me a way.

    In case anyone might see this and use it in the future, I'm presenting my solution. I decided to use the cond() function and then checked for the type of object I was dealing with. That way I can print the object differently depending on what it is. Like so:

    cond(                                                                
        (integerp(object) sprintf(object_str "%d" object))
        (floatp(object) sprintf(object_str "%g" object))
    )

    Now, I can use "%s" to print the object. And I don't have any trailing zeros for floats and integers stop at the decimanl point. And I could add a null(object) to see if there was no value, or check for equality within the cond(), etc. So I can cover all the cases I detailed above.

    It seems like a fairly simple concept now, and I appreciate your help in making this concept seem simple. Thanks again!!

    • Post Points: 5
  • Wed, Jun 17 2009 2:29 PM

    Re: RE: RE: printf() as first line and number formatting Reply

    I am getting the printing results I want, but SKILL Lint isn't so happy with one line of code. In the case where the input variable is nil, it is being fed to the else clause of an if statement and dealt with using the following code:

    sprintf(object_str "" nil)

     That works just fine and gives me the result I want, so I can print everything with a "%s" format. But although I'm happy with the code and it does just want I want, SKILL Lint doesn't give the program an IQ of 100 due to this line of code.

     What could be the problem with this line of code? Should I ignore SKILL Lint's complaint? Is there a way to make a nil variable into an empty string, printable by "%s", without making SKILL Lint gripe?

     

    As an aside, page 10 of http://www.cadence.com/rl/Resources/conference_papers/stp_cdnlive2006India_AlgroSkill.pdf shows SKILL Lint recommending a replacement of nth(1 ...) with cadr(...). Why? What about be the implications? How much weight can be given to SKILL Lint results?

    • Post Points: 20
  • Fri, Jun 19 2009 9:58 AM

    • skillUser
    • Top 10 Contributor
    • Joined on Fri, Sep 19 2008
    • Austin, TX
    • Posts 2,569
    • Points 15,600
    Re: RE: RE: printf() as first line and number formatting Reply

    Hi Evan,

    I work with SKILL in the CIC (Custom IC) tools where we have Lint also.  I suspect that the problem is that you do not have any format specifier in the formatting string. Typically you can use as a format specifier %L to print anything including 'nil' which would throw an error if used with a format like %s etc. So your example might now be:

    sprintf(object_str "%L" nil)

    However, I don't understand what you are trying to do. What do you want the string object_str to contain if the variable is nil?  I hope that this is useful information, but if not, explain what you are trying to achieve and we may be able to help you further.

    Regards,

    Lawrence.

    • Post Points: 20
  • Fri, Jun 19 2009 6:39 PM

    Re: RE: RE: printf() as first line and number formatting Reply

     Hi Lawrence,

     Thank you for the reply. What I am trying to accomplish is to make object_str an empty string when it is nil. I am creating a CSV file, using Extracta data, and on some footprints there is no footprint property so get nil for object_str. But I have to have a string, as I am printing object_str to the CSV file using "%s". So I used sprint(...) to create an empty string in the case where object_str is nil (so I have 2 consecutive commas in the CSV file).

    The line of code I posted works fine, it's just that Lint doesn't like it. Is there another way to accomplish the same thing?

    • Post Points: 20
  • Fri, Jun 19 2009 8:12 PM

    • skillUser
    • Top 10 Contributor
    • Joined on Fri, Sep 19 2008
    • Austin, TX
    • Posts 2,569
    • Points 15,600
    Re: RE: RE: printf() as first line and number formatting Reply

    Hi Evan,

    Ok, now I understand a little more about what you are trying to do.  I think that you could use the return value of the cond statement and achieve what you want that way.  Example:

    object_str = cond(
        (integerp(object) sprintf(nil "%d" object))
        (floatp(object) sprintf(nil "%g" object))
        ;; if the object is 'nil' or any unhandled case, return empty string
        (null(object) "")
        (t "")
    )

    There are still many ways that this could be done, but I believe that the above is readable and clear, and would be easy to extend if another format was needed at a later date.  The "null(object)" clause is unnecessary since the catchall (the 't' clause) provides the same result, but sometimes it is good to be verbose so that anyone reading the code is clear on the intent.

    I hope that this helps avoid any Lint trouble :-)

    Regards,

    Lawrence.

    • Post Points: 20
  • Mon, Jun 22 2009 8:59 AM

    Re: RE: RE: printf() as first line and number formatting Reply

     Hi Lawrence,

     Thank you. I was able to make it ever simpler using just an if/else statement with the else being:

    object_str = ""

    in order to get an empty string. The code works as well as it did when I used sprintf but now my Lint IQ is 100. Thanks for you help!

     

    • Post Points: 20
  • Mon, Jun 22 2009 9:54 AM

    • skillUser
    • Top 10 Contributor
    • Joined on Fri, Sep 19 2008
    • Austin, TX
    • Posts 2,569
    • Points 15,600
    Re: RE: RE: printf() as first line and number formatting Reply

    Hi Evan,

    Glad to have been some help, and that you now have the max Lint score.

    I would point out to all that SKILL Lint is a useful tool to measure the "goodness" of code, but it is entirely possible to write "bad" code which achieves a score of 100. And the converse is true also, that very good code may receive a score of less than 100 due to some nuances in the way that things are measured - sometimes there can be tricks to improve the score.

    Regards,

    Lawrence.

    Filed under:
    • Post Points: 5
Page 1 of 1 (15 items)
Sort Posts:
Started by EvanShultz at 20 May 2009 10:45 AM. Topic has 14 replies.