+static void LabelSection (void)
+/* Parse a label section */
+{
+ static const IdentTok LabelDefs[] = {
+ { "COMMENT", INFOTOK_COMMENT },
+ { "ADDR", INFOTOK_ADDR },
+ { "NAME", INFOTOK_NAME },
+ { "SIZE", INFOTOK_SIZE },
+ };
+
+ /* Locals - initialize to avoid gcc warnings */
+ char* Name = 0;
+ char* Comment = 0;
+ long Value = -1;
+ long Size = -1;
+
+ /* Skip the token */
+ InfoNextTok ();
+
+ /* Expect the opening curly brace */
+ InfoConsumeLCurly ();
+
+ /* Look for section tokens */
+ while (InfoTok != INFOTOK_RCURLY) {
+
+ /* Convert to special token */
+ InfoSpecialToken (LabelDefs, ENTRY_COUNT (LabelDefs), "Label attribute");
+
+ /* Look at the token */
+ switch (InfoTok) {
+
+ case INFOTOK_ADDR:
+ InfoNextTok ();
+ if (Value >= 0) {
+ InfoError ("Value already given");
+ }
+ InfoAssureInt ();
+ InfoRangeCheck (0, 0xFFFF);
+ Value = InfoIVal;
+ InfoNextTok ();
+ break;
+
+ case INFOTOK_COMMENT:
+ InfoNextTok ();
+ if (Comment) {
+ InfoError ("Comment already given");
+ }
+ InfoAssureStr ();
+ if (InfoSVal[0] == '\0') {
+ InfoError ("Comment may not be empty");
+ }
+ Comment = xstrdup (InfoSVal);
+ InfoNextTok ();
+ break;
+
+ case INFOTOK_NAME:
+ InfoNextTok ();
+ if (Name) {
+ InfoError ("Name already given");
+ }
+ InfoAssureStr ();
+ Name = xstrdup (InfoSVal);
+ InfoNextTok ();
+ break;
+
+ case INFOTOK_SIZE:
+ InfoNextTok ();
+ if (Size >= 0) {
+ InfoError ("Size already given");
+ }
+ InfoAssureInt ();
+ InfoRangeCheck (1, 0x10000);
+ Size = InfoIVal;
+ InfoNextTok ();
+ break;
+
+ default:
+ Internal ("Unexpected token: %u", InfoTok);
+ }
+
+ /* Directive is followed by a semicolon */
+ InfoConsumeSemi ();
+ }
+
+ /* Did we get the necessary data */
+ if (Name == 0) {
+ InfoError ("Label name is missing");
+ }
+ if (Name[0] == '\0' && Size > 1) {
+ InfoError ("Unnamed labels must not have a size > 1");
+ }
+ if (Value < 0) {
+ InfoError ("Label value is missing");
+ }
+ if (Size < 0) {
+ /* Use default */
+ Size = 1;
+ }
+ if (Value + Size > 0x10000) {
+ InfoError ("Invalid size (address out of range)");
+ }
+ if (HaveLabel ((unsigned) Value)) {
+ InfoError ("Label for address $%04lX already defined", Value);
+ }
+
+ /* Define the label(s) */
+ if (Name[0] == '\0') {
+ /* Size has already beed checked */
+ AddUnnamedLabel (Value);
+ } else {
+ AddExtLabelRange ((unsigned) Value, Name, Size);
+ }
+
+ /* Define the comment */
+ if (Comment) {
+ SetComment (Value, Comment);
+ }
+
+ /* Delete the dynamically allocated memory for Name and Comment */
+ xfree (Name);
+ xfree (Comment);
+
+ /* Consume the closing brace */
+ InfoConsumeRCurly ();
+}
+
+
+