static void WarnPragma (StrBuf* B) /* Enable/disable warnings */ { long Val; int Push; /* A warning name must follow */ IntStack* S = GetWarning (B); if (S == 0) { return; } /* Comma follows */ if (!GetComma (B)) { return; } /* Check for the "push" or "pop" keywords */ switch (ParsePushPop (B)) { case PP_NONE: Push = 0; break; case PP_PUSH: Push = 1; break; case PP_POP: /* Pop the old value and bail out */ PopInt (S); return; case PP_ERROR: /* Bail out */ return; default: Internal ("Invalid result from ParsePushPop"); } /* Boolean argument follows */ if (HasStr (B, "true") || HasStr (B, "on")) { Val = 1; } else if (HasStr (B, "false") || HasStr (B, "off")) { Val = 0; } else if (!SB_GetNumber (B, &Val)) { Error ("Invalid pragma argument"); return; } /* Set/push the new value */ if (Push) { PushInt (S, Val); } else { IS_Set (S, Val); } }
static void IntPragma (StrBuf* B, IntStack* Stack, long Low, long High) /* Handle a pragma that expects an int paramater */ { long Val; int Push; /* Check for the "push" or "pop" keywords */ switch (ParsePushPop (B)) { case PP_NONE: Push = 0; break; case PP_PUSH: Push = 1; break; case PP_POP: /* Pop the old value and bail out */ PopInt (Stack); return; case PP_ERROR: /* Bail out */ return; default: Internal ("Invalid result from ParsePushPop"); } /* Integer argument follows */ if (!GetNumber (B, &Val)) { return; } /* Check the argument */ if (Val < Low || Val > High) { Error ("Pragma argument out of bounds (%ld-%ld)", Low, High); return; } /* Set/push the new value */ if (Push) { PushInt (Stack, Val); } else { IS_Set (Stack, Val); } }
static void SegNamePragma (StrBuf* B, segment_t Seg) /* Handle a pragma that expects a segment name parameter */ { StrBuf S = AUTO_STRBUF_INITIALIZER; const char* Name; /* Check for the "push" or "pop" keywords */ int Push = 0; switch (ParsePushPop (B)) { case PP_NONE: break; case PP_PUSH: Push = 1; break; case PP_POP: /* Pop the old value and output it */ PopSegName (Seg); g_segname (Seg); /* Done */ goto ExitPoint; case PP_ERROR: /* Bail out */ goto ExitPoint; default: Internal ("Invalid result from ParsePushPop"); } /* A string argument must follow */ if (!GetString (B, &S)) { goto ExitPoint; } /* Get the string */ Name = SB_GetConstBuf (&S); /* Check if the name is valid */ if (ValidSegName (Name)) { /* Set the new name */ if (Push) { PushSegName (Seg, Name); } else { SetSegName (Seg, Name); } g_segname (Seg); } else { /* Segment name is invalid */ Error ("Illegal segment name: `%s'", Name); } ExitPoint: /* Call the string buf destructor */ SB_Done (&S); }
static void WrappedCallPragma (StrBuf* B) /* Handle the wrapped-call pragma */ { StrBuf S = AUTO_STRBUF_INITIALIZER; const char *Name; long Val; SymEntry *Entry; /* Check for the "push" or "pop" keywords */ switch (ParsePushPop (B)) { case PP_NONE: Error ("Push or pop required"); break; case PP_PUSH: break; case PP_POP: PopWrappedCall(); /* Done */ goto ExitPoint; case PP_ERROR: /* Bail out */ goto ExitPoint; default: Internal ("Invalid result from ParsePushPop"); } /* A symbol argument must follow */ if (!SB_GetSym (B, &S, NULL)) { goto ExitPoint; } /* Skip the following comma */ if (!GetComma (B)) { /* Error already flagged by GetComma */ Error ("Value required for wrapped-call identifier"); goto ExitPoint; } if (!GetNumber (B, &Val)) { Error ("Value required for wrapped-call identifier"); goto ExitPoint; } if (Val < 0 || Val > 255) { Error ("Identifier must be between 0-255"); goto ExitPoint; } /* Get the string */ Name = SB_GetConstBuf (&S); Entry = FindSym(Name); /* Check if the name is valid */ if (Entry && Entry->Flags & SC_FUNC) { PushWrappedCall(Entry, (unsigned char) Val); Entry->Flags |= SC_REF; Entry->V.F.Func->Flags |= FD_CALL_WRAPPER; } else { /* Segment name is invalid */ Error ("Wrapped-call target does not exist or is not a function"); } ExitPoint: /* Call the string buf destructor */ SB_Done (&S); }