Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!nueng.ai.mit.edu!saini From: saini@nueng.ai.mit.edu (Riju Saini) Newsgroups: gnu.g++.lib.bug Subject: (none) Message-ID: <8906062051.AA06600@nueng.> Date: 6 Jun 89 20:51:07 GMT Sender: daemon@tut.cis.ohio-state.edu Distribution: gnu Organization: GNUs Not Usenet Lines: 257 Hi, I am not sure if this is the right place to report bugs that I found in `gperf'. I am sending it here in the hope that it will be noticed by someone. Firstly let me thank the creator(s) of `gperf' for providing users with a very useful tool. I am using/experimenting various applications using `gperf'. I have almost completed writing a units conversion program, that I will submit to FSF for consideration of free distribution. Now to the bugs... I obtained cperf-1.7.tar.Z from tut.cis.ohio-state.edu and compiled (using gcc 1.34) and ran it on our Sun3-SunOS4.0 (1) The tests provided with cperf ran perfectly, but on experimenting with some of the command line switches I found gperf to generate incorrect C code for the `wordlist' structure initialization. Any combination of the '-t -p' switchs with the '-D' switch produces this error. Part of the (error) output generated on the `c-parse.gperf' file is given below: > /* C code produced by gperf version 1.7 (K&R C version) */ > /* Command-line: gperf -t -p -a -D c-parse.gperf */ > > /* Stuff deleted: The hash function is OK */ > > struct resword * > in_word_set (register char *str, register int len) > { > static struct resword wordlist[] = > { > { "switch" }, SWITCH, NORID /* Incorrect structure initialization */ > { "__asm__" }, ASM, NORID > { "register" }, SCSPEC, RID_REGISTER > { "__const__" }, TYPE_QUAL, RID_CONST > { "__inline__" }, SCSPEC, RID_INLINE > > /* ...... Stuff deleted */ > /* C code produced by gperf version 1.7 (K&R C version) */ (2) This is not a bug, but more like a suggestion for maybe an extra option... I find the use of the string comparison function `strncmp' better (under certain conditions) justified than using `strcmp'. Since the length of the string is always passed to `in_word_set' this can be implimented with relative ease, or provided as a command line option. I find the use of `strncmp' specially attractive when I want to pickup keywords from *one* large string, the keyword lengths being fixed. For example: I am trying to parse a chemical formula, say Fe2O3 (iron oxide) to construct an atom matrix consisting of the total number of atoms appearing. (For this case: Fe->2, O->3) from which one can eventually do a number of studies on the molucule. Since atoms are either 2 or 1 chars using `strcmp' on this formula gives incorrect results. If you want the function that does this job I will be willing to mail it to you. I have "fixed" these bugs and appended below is the diff for file keylist.c I hope this has been of some use. If you need more information please let me know. Thanks, Riju --------------------------------------------------------------------- Riju Saini | rsaini@helios.northeastern.edu Dept. of Chemical Engineering, | OR Northeastern University, | saini@nueng.coe.northeastern.edu Boston, MA 02115 | OR (617) 437 - 2999 | saini@nuhub.acs.northeastern.edu --------------------------------------------------------------------- *** keylist.c Tue Jun 6 14:50:43 1989 --- keylist-new.c Tue Jun 6 15:36:31 1989 *************** *** 513,519 **** for (ptr = key_list.head; ptr; ptr = ptr->next, index++) { ptr->index = index; ! printf (" %s \"%s\" %s%s\n", l_brace, ptr->key, r_brace, ptr->rest); /* Deal with links specially. */ if (ptr->link) --- 513,523 ---- for (ptr = key_list.head; ptr; ptr = ptr->next, index++) { ptr->index = index; ! printf (" %s \"%s\"", l_brace, ptr->key); ! if (ptr->rest) ! printf (",%s\t%s\n", ptr->rest, r_brace); ! else ! printf ("%s\n", r_brace); /* Deal with links specially. */ if (ptr->link) *************** *** 523,529 **** for (links = ptr->link; links; links = links->link) { links->index = ++index; ! printf (" %s \"%s\" %s%s\n", l_brace, links->key, r_brace, links->rest); } } --- 527,537 ---- for (links = ptr->link; links; links = links->link) { links->index = ++index; ! printf (" %s \"%s\"", l_brace, ptr->key); ! if (ptr->rest) ! printf (",%s\t%s\n", ptr->rest, r_brace); ! else ! printf ("%s\n", r_brace); } } *************** *** 555,561 **** LIST_NODE *links; for (links = temp; links; links = links->link) ! printf (" if (!strcmp (str, \"%s\"))\n return &wordlist[%d];\n", links->key, links->index); printf (" return 0;\n"); } --- 563,569 ---- LIST_NODE *links; for (links = temp; links; links = links->link) ! printf (" if (!strncmp (str, \"%s\", len))\n return &wordlist[%d];\n", links->key, links->index); printf (" return 0;\n"); } *************** *** 564,577 **** for ( ; temp->next && temp->hash_value == temp->next->hash_value; temp = temp->next) ! printf (" if (!strcmp (str, \"%s\"))\n return &wordlist[%d];\n", temp->key, temp->index); ! printf (" if (!strcmp (str, \"%s\"))\n return &wordlist[%d];\n return 0;\n", temp->key, temp->index); } else ! printf (" return strcmp (str, \"%s\") ? 0 : &wordlist[%d];\n", temp->key, temp->index); } } --- 572,585 ---- for ( ; temp->next && temp->hash_value == temp->next->hash_value; temp = temp->next) ! printf (" if (!strncmp (str, \"%s\", len))\n return &wordlist[%d];\n", temp->key, temp->index); ! printf (" if (!strncmp (str, \"%s\", len))\n return &wordlist[%d];\n return 0;\n", temp->key, temp->index); } else ! printf (" return strncmp (str, \"%s\", len) ? 0 : &wordlist[%d];\n", temp->key, temp->index); } } *************** *** 588,594 **** LIST_NODE *links; for (links = temp; links; links = links->link) ! printf (" if (!strcmp (str, \"%s\"))\n return \"%s\";\n", links->key, links->key); printf (" return 0;\n"); } else if (temp->next && temp->hash_value == temp->next->hash_value) --- 596,602 ---- LIST_NODE *links; for (links = temp; links; links = links->link) ! printf (" if (!strncmp (str, \"%s\", len))\n return \"%s\";\n", links->key, links->key); printf (" return 0;\n"); } else if (temp->next && temp->hash_value == temp->next->hash_value) *************** *** 596,608 **** for ( ; temp->next && temp->hash_value == temp->next->hash_value; temp = temp->next) ! printf (" if (!strcmp (str, \"%s\"))\n return \"%s\";\n", temp->key, temp->key); ! printf (" if (!strcmp (str, \"%s\"))\n return \"%s\";\n return 0;\n", temp->key, temp->key); } else ! printf (" return strcmp (str, \"%s\") ? 0 : \"%s\";\n", temp->key, temp->key); } } --- 604,616 ---- for ( ; temp->next && temp->hash_value == temp->next->hash_value; temp = temp->next) ! printf (" if (!strncmp (str, \"%s\", len))\n return \"%s\";\n", temp->key, temp->key); ! printf (" if (!strncmp (str, \"%s\", len))\n return \"%s\";\n return 0;\n", temp->key, temp->key); } else ! printf (" return strncmp (str, \"%s\", len) ? 0 : \"%s\";\n", temp->key, temp->key); } } *************** *** 618,624 **** for (temp = key_list.head; temp; temp = temp->next) printf (" case %d:\n s = \"%s\"; break;\n", temp->hash_value, temp->key); ! printf ("\n }\n return !strcmp (s, str);\n }\n }\n return 0;\n}\n"); } } --- 626,632 ---- for (temp = key_list.head; temp; temp = temp->next) printf (" case %d:\n s = \"%s\"; break;\n", temp->hash_value, temp->key); ! printf ("\n }\n return !strncmp (s, str, len);\n }\n }\n return 0;\n}\n"); } } *************** *** 790,802 **** if (OPTION_ENABLED (option, POINTER)) { ! printf (";\n\n if (%s*s == *str && !strcmp (str + 1, s + 1))\n return %s", OPTION_ENABLED (option, LENTABLE) ? "len == lengthtable[key]\n && " : "", OPTION_ENABLED (option, TYPE) ? " &wordlist[key]" : " wordlist[key]"); } else { ! printf (";\n\n return %s*s == *str && !strcmp (str + 1, s + 1)", OPTION_ENABLED (option, LENTABLE) ? "len == lengthtable[key]\n && " : ""); } printf (";\n }\n }\n return 0;\n}\n"); --- 798,810 ---- if (OPTION_ENABLED (option, POINTER)) { ! printf (";\n\n if (%s*s == *str && !strncmp (str + 1, s + 1, len - 1))\n return %s", OPTION_ENABLED (option, LENTABLE) ? "len == lengthtable[key]\n && " : "", OPTION_ENABLED (option, TYPE) ? " &wordlist[key]" : " wordlist[key]"); } else { ! printf (";\n\n return %s*s == *str && !strncmp (str + 1, s + 1, len - 1)", OPTION_ENABLED (option, LENTABLE) ? "len == lengthtable[key]\n && " : ""); } printf (";\n }\n }\n return 0;\n}\n");