diff options
| -rw-r--r-- | src/game/edge_version.h | 3 | ||||
| -rw-r--r-- | src/game/g_admin.c | 315 | ||||
| -rw-r--r-- | src/game/g_admin.h | 4 | ||||
| -rw-r--r-- | src/game/g_buildable.c | 19 | ||||
| -rw-r--r-- | src/game/g_cmds.c | 277 | ||||
| -rw-r--r-- | src/game/g_combat.c | 54 | ||||
| -rw-r--r-- | src/game/g_local.h | 1 | ||||
| -rw-r--r-- | src/game/g_main.c | 16 | ||||
| -rw-r--r-- | src/game/g_svcmds.c | 3 | ||||
| -rw-r--r-- | src/game/newedge_version.h | 3 | ||||
| -rw-r--r-- | src/tools/lcc/lburg/gram.c | 1686 | 
11 files changed, 2068 insertions, 313 deletions
diff --git a/src/game/edge_version.h b/src/game/edge_version.h deleted file mode 100644 index 6cf5772..0000000 --- a/src/game/edge_version.h +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef EDGE_MOD_VERSION -#define EDGE_MOD_VERSION "7.7b" -#endif diff --git a/src/game/g_admin.c b/src/game/g_admin.c index 6c04029..0fbac12 100644 --- a/src/game/g_admin.c +++ b/src/game/g_admin.c @@ -164,6 +164,16 @@ g_admin_cmd_t g_admin_cmds[ ] =        "[^7a|h^7]"      }, +    {"m", G_admin_m, qfalse, "say", +      "send a private message", +      "[^7name|slot#^7] [^7message^7]" +    }, + +    {"mt", G_admin_m, qfalse, "say_team", +      "send a team-only private message", +      "[^7name|slot#^7] [^7message^7]" +    }, +      {"mute", G_admin_mute, qfalse, "mute",        "mute a player",        "[^7name|slot#^7]" @@ -220,6 +230,21 @@ g_admin_cmd_t g_admin_cmds[ ] =        "[^7id^7]"      }, +    {"say", G_admin_say, qfalse, "say", +      "say in the public chat", +      "[^7message^7]" +    }, + +    {"say_area", G_admin_say_area, qfalse, "say_area", +      "say to nearby players", +      "[^7message^7]" +    }, + +    {"say_team", G_admin_say, qfalse, "say_team", +      "say in the team chat", +      "[^7message^7]" +    }, +      {"score_info", G_admin_score_info, qtrue, "score_info",       "display information about player's accumulated score",       "(^7name|slot#^7) [^7newscore^7]" @@ -278,12 +303,28 @@ g_admin_cmd_t g_admin_cmds[ ] =        "[^7name|slot#^7]"      }, + +    {"vsay", G_admin_vsay, qfalse, "say", +      "n/a", +      "n/a" +    }, + +    {"vsay_local", G_admin_vsay, qfalse, "say_team", +      "n/a", +      "n/a" +    }, + +    {"vsay_team", G_admin_vsay, qfalse, "say_team", +      "n/a", +      "n/a" +    }, +      {       "warn", G_admin_warn, qfalse, "warn",        "warn a player to correct their current activity",        "[^7name|slot#^7] [^7reason^7]"      } -  }; +};  static size_t adminNumCmds = sizeof( g_admin_cmds ) / sizeof( g_admin_cmds[ 0 ] ); @@ -825,8 +866,8 @@ static void admin_log_abort( void )  static void admin_log_end( const qboolean ok )  { -  if( adminLog[ 0 ] ) -    G_LogPrintf( "AdminExec: %s: %s\n", ok ? "ok" : "fail", adminLog ); +  if( adminLog[ 0 ] && !ok ) +    G_LogPrintf( "AdminExec: fail: %s\n", adminLog );    admin_log_abort( );  } @@ -4544,3 +4585,271 @@ void G_admin_writeconfig( void )  {    if ( g_admin_levels ) admin_writeconfig( );  } + +/* +================== +G_admin_say_area +================== +*/ +qboolean G_admin_say_area( gentity_t *ent ) +{ +  int    entityList[ MAX_GENTITIES ]; +  int    num, i; +  vec3_t range = { 1000.0f, 1000.0f, 1000.0f }; +  vec3_t mins, maxs; +  char   *msg; + +  if( trap_Argc( ) < 2 ) +  { +    ADMP( "usage: say_area [message]\n" ); +    return qfalse; +  } + +  msg = ConcatArgs( 1 ); + +  for(i = 0; i < 3; i++ ) +    range[ i ] = g_sayAreaRange.value; + +  G_LogPrintf( "SayArea: %d \"%s" S_COLOR_WHITE "\": " S_COLOR_BLUE "%s\n", +    ent - g_entities, ent->client->pers.netname, msg ); + +  VectorAdd( ent->s.origin, range, maxs ); +  VectorSubtract( ent->s.origin, range, mins ); + +  num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); +  for( i = 0; i < num; i++ ) +    G_SayTo( ent, &g_entities[ entityList[ i ] ], SAY_AREA, msg ); + +  //Send to ADMF_SPEC_ALLCHAT candidates +  for( i = 0; i < level.maxclients; i++ ) +  { +    if( g_entities[ i ].client->pers.teamSelection == TEAM_NONE && +        G_admin_permission( &g_entities[ i ], ADMF_SPEC_ALLCHAT ) ) +    { +      G_SayTo( ent, &g_entities[ i ], SAY_AREA, msg ); +    } +  } + +  return qtrue; +} + + +/* +================== +G_admin_say +================== +*/ +qboolean G_admin_say( gentity_t *ent ) +{ +  char    *p; +  char    cmd[ MAX_TOKEN_CHARS ]; +  saymode_t mode = SAY_ALL; + +  if( trap_Argc( ) < 2 ) +    return qfalse; + +  trap_Argv( 0, cmd, sizeof( cmd ) ); +  if( Q_stricmp( cmd, "say_team" ) == 0 ) +    mode = SAY_TEAM; + +  p = ConcatArgs( 1 ); + +  G_Say( ent, mode, p ); + return qtrue; +} + +/* +================== +G_admin_vsay +================== +*/ +qboolean G_admin_vsay( gentity_t *ent ) +{ +  char            arg[MAX_TOKEN_CHARS]; +  char            text[ MAX_TOKEN_CHARS ]; +  voiceChannel_t  vchan; +  voice_t         *voice; +  voiceCmd_t      *cmd; +  voiceTrack_t    *track; +  int             cmdNum = 0; +  int             trackNum = 0; +  char            voiceName[ MAX_VOICE_NAME_LEN ] = {"default"}; +  char            voiceCmd[ MAX_VOICE_CMD_LEN ] = {""}; +  char            vsay[ 12 ] = {""}; +  weapon_t        weapon; + +  if( !ent || !ent->client ) +    return qfalse; + +  trap_Argv( 0, arg, sizeof( arg ) ); +  if( trap_Argc( ) < 2 ) +  { +    trap_SendServerCommand( ent-g_entities, va( +      "print \"usage: %s command [text] \n\"", arg ) ); +    return qfalse; +  } +  if( !level.voices ) +  { +    trap_SendServerCommand( ent-g_entities, va( +      "print \"%s: voice system is not installed on this server\n\"", arg ) ); +    return qfalse; +  } +  if( !g_voiceChats.integer ) +  { +    trap_SendServerCommand( ent-g_entities, va( +      "print \"%s: voice system administratively disabled on this server\n\"", +      arg ) ); +    return qfalse; +  } +  if( !Q_stricmp( arg, "vsay" ) ) +    vchan = VOICE_CHAN_ALL; +  else if( !Q_stricmp( arg, "vsay_team" ) ) +    vchan = VOICE_CHAN_TEAM; +  else if( !Q_stricmp( arg, "vsay_local" ) ) +    vchan = VOICE_CHAN_LOCAL; +  else +    return qfalse; +  Q_strncpyz( vsay, arg, sizeof( vsay ) ); + +  if( ent->client->pers.voice[ 0 ] ) +    Q_strncpyz( voiceName, ent->client->pers.voice, sizeof( voiceName ) ); +  voice = BG_VoiceByName( level.voices, voiceName ); +  if( !voice ) +  { +    trap_SendServerCommand( ent-g_entities, va( +      "print \"%s: voice '%s' not found\n\"", vsay, voiceName ) ); +    return qfalse; +  } + +  trap_Argv( 1, voiceCmd, sizeof( voiceCmd ) ) ; +  cmd = BG_VoiceCmdFind( voice->cmds, voiceCmd, &cmdNum ); +  if( !cmd ) +  { +    trap_SendServerCommand( ent-g_entities, va( +     "print \"%s: command '%s' not found in voice '%s'\n\"", +      vsay, voiceCmd, voiceName ) ); +    return qfalse; +  } + +  // filter non-spec humans by their primary weapon as well +  weapon = WP_NONE; +  if( ent->client->sess.spectatorState == SPECTATOR_NOT ) +  { +    weapon = BG_PrimaryWeapon( ent->client->ps.stats ); +  } + +  track = BG_VoiceTrackFind( cmd->tracks, ent->client->pers.teamSelection, +    ent->client->pers.classSelection, weapon, (int)ent->client->voiceEnthusiasm, +    &trackNum ); +  if( !track ) +  { +    trap_SendServerCommand( ent-g_entities, va( +      "print \"%s: no available track for command '%s', team %d, " +      "class %d, weapon %d, and enthusiasm %d in voice '%s'\n\"", +      vsay, voiceCmd, ent->client->pers.teamSelection, +      ent->client->pers.classSelection, weapon, +      (int)ent->client->voiceEnthusiasm, voiceName ) ); +    return qfalse; +  } + +  if( !Q_stricmp( ent->client->lastVoiceCmd, cmd->cmd ) ) +    ent->client->voiceEnthusiasm++; + +  Q_strncpyz( ent->client->lastVoiceCmd, cmd->cmd, +    sizeof( ent->client->lastVoiceCmd ) ); + +  // optional user supplied text +  trap_Argv( 2, arg, sizeof( arg ) ); +  G_CensorString( text, arg, sizeof( text ), ent ); + +  switch( vchan ) +  { +    case VOICE_CHAN_ALL: +    case VOICE_CHAN_LOCAL: +      trap_SendServerCommand( -1, va( +        "voice %d %d %d %d \"%s\"\n", +        (int)(ent-g_entities), vchan, cmdNum, trackNum, text ) ); +      break; +    case VOICE_CHAN_TEAM: +      G_TeamCommand( ent->client->pers.teamSelection, va( +        "voice %d %d %d %d \"%s\"\n", +        (int)(ent-g_entities), vchan, cmdNum, trackNum, text ) ); +      break; +    default: +      break; +  } + +	return qtrue; +} + +qboolean G_admin_m( gentity_t *ent ) +{ +  int pids[ MAX_CLIENTS ]; +  char name[ MAX_NAME_LENGTH ]; +  char cmd[ 12 ]; +  char text[ MAX_STRING_CHARS ]; +  char *msg; +  char color; +  int i, pcount; +  int count = 0; +  qboolean teamonly = qfalse; +  char recipients[ MAX_STRING_CHARS ] = ""; + +  if( !g_privateMessages.integer && ent ) +  { +    ADMP( "Sorry, but private messages have been disabled\n" ); +    return qfalse; +  } + +  trap_Argv( 0, cmd, sizeof( cmd ) ); +  if( trap_Argc( ) < 3 ) +  { +    ADMP( va( "usage: %s [name|slot#] [message]\n", cmd ) ); +    return qfalse; +  } + +  if( !Q_stricmp( cmd, "mt" ) ) +    teamonly = qtrue; + +  trap_Argv( 1, name, sizeof( name ) ); +  msg = ConcatArgs( 2 ); +  pcount = G_ClientNumbersFromString( name, pids, MAX_CLIENTS ); + +  G_CensorString( text, msg, sizeof( text ), ent ); + +  // send the message +  for( i = 0; i < pcount; i++ ) +  { +    if( G_SayTo( ent, &g_entities[ pids[ i ] ], +        teamonly ? SAY_TPRIVMSG : SAY_PRIVMSG, text ) ) +    { +      count++; +      Q_strcat( recipients, sizeof( recipients ), va( "%s" S_COLOR_WHITE ", ", +        level.clients[ pids[ i ] ].pers.netname ) ); +    } +  } + +  // report the results +  color = teamonly ? COLOR_CYAN : COLOR_YELLOW; + +  if( !count ) +    ADMP( va( "^3No player matching ^7\'%s^7\' ^3to send message to.\n", +      name ) ); +  else +  { +    ADMP( va( "^%cPrivate message: ^7%s\n", color, text ) ); +    // remove trailing ", " +    recipients[ strlen( recipients ) - 2 ] = '\0'; +    ADMP( va( "^%csent to %i player%s: " S_COLOR_WHITE "%s\n", color, count, +      count == 1 ? "" : "s", recipients ) ); + +    G_LogPrintf( "%s: %d \"%s" S_COLOR_WHITE "\" \"%s\": ^%c%s\n", +      ( teamonly ) ? "TPrivMsg" : "PrivMsg", +      ( ent ) ? ent - g_entities : -1, +      ( ent ) ? ent->client->pers.netname : "console", +      name, color, msg ); +  } + +  return qtrue; +} + diff --git a/src/game/g_admin.h b/src/game/g_admin.h index 8132607..6f8cc0b 100644 --- a/src/game/g_admin.h +++ b/src/game/g_admin.h @@ -207,6 +207,10 @@ qboolean G_admin_flaglist( gentity_t *ent );  qboolean G_admin_flag( gentity_t *ent );  qboolean G_admin_slap( gentity_t *ent );  qboolean G_admin_stats( gentity_t *ent ); +qboolean G_admin_say_area( gentity_t *ent ); +qboolean G_admin_say( gentity_t *ent ); +qboolean G_admin_vsay( gentity_t *ent ); +qboolean G_admin_m( gentity_t *ent );  g_admin_level_t *G_admin_find_level_for_score( int score );  void G_admin_add_score( gentity_t *ent, int score ); diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c index 19e7199..6d42335 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -322,7 +322,7 @@ buildable_t G_IsPowered( vec3_t origin )      return BA_NONE;  } - /* +/*  ================  G_IsGathered @@ -4189,6 +4189,7 @@ itemBuildError_t G_CanBuild( gentity_t *ent, buildable_t buildable, int distance    qboolean          invert;    int               contents;    playerState_t     *ps = &ent->client->ps; +  float             d;    // Stop all buildables from interacting with traces    //G_SetBuildableLinkState( qfalse ); @@ -4256,7 +4257,13 @@ itemBuildError_t G_CanBuild( gentity_t *ent, buildable_t buildable, int distance  	break;        case 2: // Creeps/colonies block building for enemy team  	if( G_IsGathered( TEAM_HUMANS, entity_origin, qfalse, ent ) ) -          reason = IBE_BLOCKEDBYENEMY; +	{ +	  tempent = G_Overmind( ); +	  if( tempent != NULL ) { +	    d = Distance( tempent->s.origin, entity_origin ); +	    if ( d > CREEP_BASESIZE ) reason = IBE_BLOCKEDBYENEMY; +	  } else reason = IBE_BLOCKEDBYENEMY; +	}  	break;        default:          if( G_IsPowered( entity_origin ) != BA_NONE ) @@ -4304,7 +4311,13 @@ itemBuildError_t G_CanBuild( gentity_t *ent, buildable_t buildable, int distance            reason = IBE_BLOCKEDBYENEMY;        case 2: // Creeps/colonies block building for enemy team  	if( G_IsGathered( TEAM_ALIENS, entity_origin, qfalse, ent ) ) -	reason = IBE_BLOCKEDBYENEMY; +	{ +	  tempent = G_Reactor( ); +	  if( tempent != NULL ) { +	    d = Distance( tempent->s.origin, entity_origin ); +	    if ( d > REACTOR_BASESIZE ) reason = IBE_BLOCKEDBYENEMY; +	  } else reason = IBE_BLOCKEDBYENEMY; +        }  	break;        default:  	if( G_IsCreepHere( entity_origin ) ) diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index eab8631..f3cada7 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -935,11 +935,15 @@ static qboolean G_SayTo( gentity_t *ent, gentity_t *other, saymode_t mode, const      return qfalse;    if( !other->client ) -    return qfalse; +    return qfalse;                  if( other->client->pers.connected != CON_CONNECTED )      return qfalse; +  // ignore messages from people in /ignore list +  if( Com_ClientListContains( &other->client->sess.ignoreList, (int)( ent - g_entities ) ) ) +    return qfalse; +      if( ( ent && !OnSameTeam( ent, other ) ) &&        ( mode == SAY_TEAM || mode == SAY_AREA || mode == SAY_TPRIVMSG ) )    { @@ -1007,198 +1011,6 @@ void G_Say( gentity_t *ent, saymode_t mode, const char *chatText )      G_SayTo( ent, other, mode, text );    }  } - -/* -================== -Cmd_SayArea_f -================== -*/ -static void Cmd_SayArea_f( gentity_t *ent ) -{ -  int    entityList[ MAX_GENTITIES ]; -  int    num, i; -  vec3_t range = { 1000.0f, 1000.0f, 1000.0f }; -  vec3_t mins, maxs; -  char   *msg; - -  if( trap_Argc( ) < 2 ) -  { -    ADMP( "usage: say_area [message]\n" ); -    return; -  } - -  msg = ConcatArgs( 1 ); - -  for(i = 0; i < 3; i++ ) -    range[ i ] = g_sayAreaRange.value; - -  G_LogPrintf( "SayArea: %d \"%s" S_COLOR_WHITE "\": " S_COLOR_BLUE "%s\n", -    ent - g_entities, ent->client->pers.netname, msg ); - -  VectorAdd( ent->s.origin, range, maxs ); -  VectorSubtract( ent->s.origin, range, mins ); - -  num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); -  for( i = 0; i < num; i++ ) -    G_SayTo( ent, &g_entities[ entityList[ i ] ], SAY_AREA, msg ); - -  //Send to ADMF_SPEC_ALLCHAT candidates -  for( i = 0; i < level.maxclients; i++ ) -  { -    if( g_entities[ i ].client->pers.teamSelection == TEAM_NONE && -        G_admin_permission( &g_entities[ i ], ADMF_SPEC_ALLCHAT ) ) -    { -      G_SayTo( ent, &g_entities[ i ], SAY_AREA, msg ); -    } -  } -} - - -/* -================== -Cmd_Say_f -================== -*/ -static void Cmd_Say_f( gentity_t *ent ) -{ -  char    *p; -  char    cmd[ MAX_TOKEN_CHARS ]; -  saymode_t mode = SAY_ALL; - -  if( trap_Argc( ) < 2 ) -    return; - -  trap_Argv( 0, cmd, sizeof( cmd ) ); -  if( Q_stricmp( cmd, "say_team" ) == 0 ) -    mode = SAY_TEAM; - -  p = ConcatArgs( 1 ); - -  G_Say( ent, mode, p ); -} - -/* -================== -Cmd_VSay_f -================== -*/ -void Cmd_VSay_f( gentity_t *ent ) -{ -  char            arg[MAX_TOKEN_CHARS]; -  char            text[ MAX_TOKEN_CHARS ]; -  voiceChannel_t  vchan; -  voice_t         *voice; -  voiceCmd_t      *cmd; -  voiceTrack_t    *track; -  int             cmdNum = 0; -  int             trackNum = 0; -  char            voiceName[ MAX_VOICE_NAME_LEN ] = {"default"}; -  char            voiceCmd[ MAX_VOICE_CMD_LEN ] = {""}; -  char            vsay[ 12 ] = {""}; -  weapon_t        weapon; - -  if( !ent || !ent->client ) -    Com_Error( ERR_FATAL, "Cmd_VSay_f() called by non-client entity\n" ); - -  trap_Argv( 0, arg, sizeof( arg ) ); -  if( trap_Argc( ) < 2 ) -  { -    trap_SendServerCommand( ent-g_entities, va( -      "print \"usage: %s command [text] \n\"", arg ) ); -    return; -  } -  if( !level.voices ) -  { -    trap_SendServerCommand( ent-g_entities, va( -      "print \"%s: voice system is not installed on this server\n\"", arg ) ); -    return; -  } -  if( !g_voiceChats.integer ) -  { -    trap_SendServerCommand( ent-g_entities, va( -      "print \"%s: voice system administratively disabled on this server\n\"", -      arg ) ); -    return; -  } -  if( !Q_stricmp( arg, "vsay" ) ) -    vchan = VOICE_CHAN_ALL; -  else if( !Q_stricmp( arg, "vsay_team" ) ) -    vchan = VOICE_CHAN_TEAM; -  else if( !Q_stricmp( arg, "vsay_local" ) ) -    vchan = VOICE_CHAN_LOCAL; -  else -    return; -  Q_strncpyz( vsay, arg, sizeof( vsay ) ); - -  if( ent->client->pers.voice[ 0 ] ) -    Q_strncpyz( voiceName, ent->client->pers.voice, sizeof( voiceName ) ); -  voice = BG_VoiceByName( level.voices, voiceName ); -  if( !voice ) -  { -    trap_SendServerCommand( ent-g_entities, va( -      "print \"%s: voice '%s' not found\n\"", vsay, voiceName ) ); -    return; -  } - -  trap_Argv( 1, voiceCmd, sizeof( voiceCmd ) ) ; -  cmd = BG_VoiceCmdFind( voice->cmds, voiceCmd, &cmdNum ); -  if( !cmd ) -  { -    trap_SendServerCommand( ent-g_entities, va( -     "print \"%s: command '%s' not found in voice '%s'\n\"", -      vsay, voiceCmd, voiceName ) ); -    return; -  } - -  // filter non-spec humans by their primary weapon as well -  weapon = WP_NONE; -  if( ent->client->sess.spectatorState == SPECTATOR_NOT ) -  { -    weapon = BG_PrimaryWeapon( ent->client->ps.stats ); -  } - -  track = BG_VoiceTrackFind( cmd->tracks, ent->client->pers.teamSelection, -    ent->client->pers.classSelection, weapon, (int)ent->client->voiceEnthusiasm, -    &trackNum ); -  if( !track ) -  { -    trap_SendServerCommand( ent-g_entities, va( -      "print \"%s: no available track for command '%s', team %d, " -      "class %d, weapon %d, and enthusiasm %d in voice '%s'\n\"", -      vsay, voiceCmd, ent->client->pers.teamSelection, -      ent->client->pers.classSelection, weapon, -      (int)ent->client->voiceEnthusiasm, voiceName ) ); -    return; -  } - -  if( !Q_stricmp( ent->client->lastVoiceCmd, cmd->cmd ) ) -    ent->client->voiceEnthusiasm++; - -  Q_strncpyz( ent->client->lastVoiceCmd, cmd->cmd, -    sizeof( ent->client->lastVoiceCmd ) ); - -  // optional user supplied text -  trap_Argv( 2, arg, sizeof( arg ) ); -  G_CensorString( text, arg, sizeof( text ), ent ); - -  switch( vchan ) -  { -    case VOICE_CHAN_ALL: -    case VOICE_CHAN_LOCAL: -      trap_SendServerCommand( -1, va( -        "voice %d %d %d %d \"%s\"\n", -        (int)(ent-g_entities), vchan, cmdNum, trackNum, text ) ); -      break; -    case VOICE_CHAN_TEAM: -      G_TeamCommand( ent->client->pers.teamSelection, va( -        "voice %d %d %d %d \"%s\"\n", -        (int)(ent-g_entities), vchan, cmdNum, trackNum, text ) ); -      break; -    default: -      break; -  } -} -  /*  ==================  Cmd_Where_f @@ -3637,19 +3449,14 @@ commands_t cmds[ ] = {    { "itemtoggle", CMD_HUMAN|CMD_LIVING, Cmd_ToggleItem_f },    { "kill", CMD_TEAM|CMD_LIVING, Cmd_Kill_f },    { "levelshot", CMD_CHEAT, Cmd_LevelShot_f }, -  { "listmaps", CMD_MESSAGE|CMD_INTERMISSION, Cmd_ListMaps_f },    { "listemoticons", CMD_MESSAGE|CMD_INTERMISSION, Cmd_ListEmoticons_f }, -  { "m", CMD_MESSAGE|CMD_INTERMISSION, Cmd_PrivateMessage_f }, +  { "listmaps", CMD_MESSAGE|CMD_INTERMISSION, Cmd_ListMaps_f },    { "maplog", CMD_MESSAGE|CMD_INTERMISSION, Cmd_MapLog_f }, -  { "mt", CMD_MESSAGE|CMD_INTERMISSION, Cmd_PrivateMessage_f },    { "myscore", 0, Cmd_MyScore_f },    { "noclip", CMD_CHEAT_TEAM, Cmd_Noclip_f },    { "notarget", CMD_CHEAT|CMD_TEAM|CMD_LIVING, Cmd_Notarget_f },    { "reload", CMD_HUMAN|CMD_LIVING, Cmd_Reload_f },    { "rotation", CMD_MESSAGE|CMD_INTERMISSION, Cmd_MapRotation_f }, -  { "say", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Say_f }, -  { "say_area", CMD_MESSAGE|CMD_TEAM|CMD_LIVING, Cmd_SayArea_f }, -  { "say_team", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Say_f },    { "score", CMD_INTERMISSION, ScoreboardMessage },    { "sell", CMD_HUMAN|CMD_LIVING, Cmd_Sell_f },    { "setviewpos", CMD_CHEAT_TEAM, Cmd_SetViewpos_f }, @@ -3658,9 +3465,6 @@ commands_t cmds[ ] = {    { "test", CMD_CHEAT, Cmd_Test_f },    { "unignore", 0, Cmd_Ignore_f },    { "vote", 0, Cmd_Vote_f }, -  { "vsay", CMD_MESSAGE|CMD_INTERMISSION, Cmd_VSay_f }, -  { "vsay_local", CMD_MESSAGE|CMD_INTERMISSION, Cmd_VSay_f }, -  { "vsay_team", CMD_MESSAGE|CMD_INTERMISSION, Cmd_VSay_f },    { "where", 0, Cmd_Where_f }  };  static size_t numCmds = sizeof( cmds ) / sizeof( cmds[ 0 ] ); @@ -3835,75 +3639,6 @@ void Cmd_MyScore_f( gentity_t *ent )    }  } -void Cmd_PrivateMessage_f( gentity_t *ent ) -{ -  int pids[ MAX_CLIENTS ]; -  char name[ MAX_NAME_LENGTH ]; -  char cmd[ 12 ]; -  char text[ MAX_STRING_CHARS ]; -  char *msg; -  char color; -  int i, pcount; -  int count = 0; -  qboolean teamonly = qfalse; -  char recipients[ MAX_STRING_CHARS ] = ""; - -  if( !g_privateMessages.integer && ent ) -  { -    ADMP( "Sorry, but private messages have been disabled\n" ); -    return; -  } - -  trap_Argv( 0, cmd, sizeof( cmd ) ); -  if( trap_Argc( ) < 3 ) -  { -    ADMP( va( "usage: %s [name|slot#] [message]\n", cmd ) ); -    return; -  } - -  if( !Q_stricmp( cmd, "mt" ) ) -    teamonly = qtrue; - -  trap_Argv( 1, name, sizeof( name ) ); -  msg = ConcatArgs( 2 ); -  pcount = G_ClientNumbersFromString( name, pids, MAX_CLIENTS ); - -  G_CensorString( text, msg, sizeof( text ), ent ); - -  // send the message -  for( i = 0; i < pcount; i++ ) -  { -    if( G_SayTo( ent, &g_entities[ pids[ i ] ], -        teamonly ? SAY_TPRIVMSG : SAY_PRIVMSG, text ) ) -    { -      count++; -      Q_strcat( recipients, sizeof( recipients ), va( "%s" S_COLOR_WHITE ", ", -        level.clients[ pids[ i ] ].pers.netname ) ); -    } -  } - -  // report the results -  color = teamonly ? COLOR_CYAN : COLOR_YELLOW; - -  if( !count ) -    ADMP( va( "^3No player matching ^7\'%s^7\' ^3to send message to.\n", -      name ) ); -  else -  { -    ADMP( va( "^%cPrivate message: ^7%s\n", color, text ) ); -    // remove trailing ", " -    recipients[ strlen( recipients ) - 2 ] = '\0'; -    ADMP( va( "^%csent to %i player%s: " S_COLOR_WHITE "%s\n", color, count, -      count == 1 ? "" : "s", recipients ) ); - -    G_LogPrintf( "%s: %d \"%s" S_COLOR_WHITE "\" \"%s\": ^%c%s\n", -      ( teamonly ) ? "TPrivMsg" : "PrivMsg", -      ( ent ) ? ent - g_entities : -1, -      ( ent ) ? ent->client->pers.netname : "console", -      name, color, msg ); -  } -} -  /*  =================  Cmd_AdminMessage_f diff --git a/src/game/g_combat.c b/src/game/g_combat.c index b0e33e4..966e595 100644 --- a/src/game/g_combat.c +++ b/src/game/g_combat.c @@ -194,20 +194,21 @@ float G_CamperRewardBonus(  gentity_t *self )  float G_RewardScaleFactor( gentity_t *self, gentity_t *target )  {    float targetScore; -  if( !target->client ) return 1.0f;    if( level.humanRewardScore <= 0.0f || level.alienRewardScore <= 0.0f ) return 1.0f; -  if( self->client->ps.persistant[ PERS_SCORE ] <= 0 || target->client->ps.persistant[ PERS_SCORE ] <= 0) return 1.0f; -  targetScore = target->client->ps.persistant[ PERS_SCORE ]/self->client->ps.persistant[ PERS_SCORE ]; -  switch( target->client->ps.stats[ STAT_TEAM ] ) { +  switch( self->client->ps.stats[ STAT_TEAM ] ) {    case TEAM_ALIENS: -    targetScore *= level.alienRewardScore/level.humanRewardScore; +    targetScore = level.humanRewardScore/level.alienRewardScore;      break;    case TEAM_HUMANS: -    targetScore *= level.humanRewardScore/level.alienRewardScore; +    targetScore = level.alienRewardScore/level.humanRewardScore;      break;    default:      return 0;    } +  if ( target->client != NULL ) { +    if( self->client->ps.persistant[ PERS_SCORE ] <= 0 || target->client->ps.persistant[ PERS_SCORE ] <= 0) return targetScore; +    targetScore *= target->client->ps.persistant[ PERS_SCORE ]/self->client->ps.persistant[ PERS_SCORE ]; +  }    targetScore *= 1.0f-g_ConstantRewardFactor.value;    targetScore += g_ConstantRewardFactor.value;    if (targetScore < g_MinRewardFactor.value) targetScore = g_MinRewardFactor.value; @@ -219,31 +220,40 @@ float G_RewardScaleFactor( gentity_t *self, gentity_t *target )  float G_InstantRewardAttacker( gentity_t *self, gentity_t *target, float damage )  {    float value; -  int maxHealth; +  int maxHealth,targetTeam;    if( damage <= 0.f ) return 0.0f;    if( !self->client ) return 0.0f; -  if( !target->client ) return 0.0f; -  if( OnSameTeam( self, target ) ) return 0.0f; -  if( target->s.eType == ET_BUILDABLE ) return 0.0f; -  maxHealth = target->client->ps.stats[ STAT_MAX_HEALTH ]; +  if( target->client != NULL ) { +    maxHealth = target->client->ps.stats[ STAT_MAX_HEALTH ]; +    targetTeam = target->client->ps.stats[ STAT_TEAM ]; +  } else { +    maxHealth = BG_Buildable( target->s.modelindex )->health; +    targetTeam = target->buildableTeam; +  } +  if( targetTeam == self->client->ps.stats[ STAT_TEAM ] ) return 0.0f; -  // Only give credits for attacking players for now    value = damage / maxHealth;    if (value > 1.0f) value = 1.0f; -  value *= G_CamperRewardBonus( target ); -  value *= BG_GetValueOfPlayer( &target->client->ps ); -  if( target->client->ps.stats[ STAT_TEAM ] == TEAM_ALIENS) { +  if( target->client != NULL ) { +    value *= G_CamperRewardBonus( target ); +    value *= BG_GetValueOfPlayer( &target->client->ps ); +  } else { +    value *= BG_Buildable( target->s.modelindex )->value; +    value *= g_BuildingCreditsFactor.value; +  } + +  if( targetTeam == TEAM_ALIENS) {      value *= g_InstantRewardMultiplierA.value; -  } else if( target->client->ps.stats[ STAT_TEAM ] == TEAM_HUMANS ) { +  } else if( targetTeam == TEAM_HUMANS ) {      value *= g_InstantRewardMultiplierH.value; -  } else value = 0; +  } else value = 0.f;    value *= G_RewardScaleFactor( self, target ); -  if( value > 0 ) { +  if( value > 0.f ) {      G_AddCreditToClient( self->client, value, qtrue );      if( self->client->ps.stats[ STAT_TEAM ] == TEAM_ALIENS ) {        trap_Cvar_Set( "g_alienCredits", @@ -334,12 +344,12 @@ float G_RewardAttackers( gentity_t *self )        AddScore( player, stageValue ); -      // killing buildables earns score, but not credits -      if( self->s.eType != ET_BUILDABLE ) -      { +      // killing buildables earns score, but not credits unless g_BuildingCreditsFactor > 0 +      if( self->s.eType == ET_BUILDABLE ) stageValue *= g_BuildingCreditsFactor.value; +      if( stageValue > 0 ) {  	// Com_Printf(S_COLOR_YELLOW "Killer: kills = %f deaths = %f percent_of_damage = %f -> factor = %f\n",player->client->pers.kills,player->client->pers.deaths,killValue,G_RewardScaleFactor( player, self, teamFactor) );  	stageValue *= G_RewardScaleFactor( player, self ); -	player->client->pers.kills += killValue; +	player->client->pers.kills += killValue; // NOTE: Building kills will increase this too if g_BuildingCreditsFactor > 0          // add to stage counters          if( player->client->ps.stats[ STAT_TEAM ] == TEAM_ALIENS ) {  	  G_AddCreditToClient( player->client, g_KillRewardMultiplierH.value*stageValue, qtrue ); diff --git a/src/game/g_local.h b/src/game/g_local.h index a8b2323..9cc0ff2 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -1380,6 +1380,7 @@ extern  vmCvar_t  g_MinAlienExtraBuildPoints;  extern  vmCvar_t  g_MaxAlienExtraBuildPoints;  extern  vmCvar_t  g_MinHumanExtraBuildPoints;  extern  vmCvar_t  g_MaxHumanExtraBuildPoints; +extern  vmCvar_t  g_BuildingCreditsFactor;  void      trap_Print( const char *fmt );  void      trap_Error( const char *fmt ); diff --git a/src/game/g_main.c b/src/game/g_main.c index 0466d01..2d0c788 100644 --- a/src/game/g_main.c +++ b/src/game/g_main.c @@ -26,12 +26,9 @@ TREMULOUS EDGE MOD SRC FILE  ===========================================================================  */  #include "g_local.h" -#include "edge_version.h" +#include "newedge_version.h"  #define G_MOD_VERSION "Aardvark 0.5x" SVN_VERSION -#ifndef EDGE_MOD_VERSION -#define EDGE_MOD_VERSION "7.5.x" -#endif  level_locals_t  level;  typedef struct @@ -209,6 +206,8 @@ vmCvar_t  g_MinAlienExtraBuildPoints;  vmCvar_t  g_MaxAlienExtraBuildPoints;  vmCvar_t  g_MinHumanExtraBuildPoints;  vmCvar_t  g_MaxHumanExtraBuildPoints; +vmCvar_t  g_BuildingCreditsFactor; +  // copy cvars that can be set in worldspawn so they can be restored later  static char cv_gravity[ MAX_CVAR_VALUE_STRING ]; @@ -224,7 +223,7 @@ static cvarTable_t   gameCvarTable[ ] =    { NULL, "gamename", GAME_VERSION , CVAR_SERVERINFO | CVAR_ROM, 0, qfalse  },    { NULL, "gamedate", __DATE__ , CVAR_ROM, 0, qfalse  },    { NULL, "g_version", G_MOD_VERSION , CVAR_SERVERINFO | CVAR_ROM, 0, qfalse  }, -  { NULL, "edge_version", EDGE_MOD_VERSION , CVAR_SERVERINFO | CVAR_ROM, 0, qfalse  }, +  { NULL, "newedge_version", NEWEDGE_MOD_VERSION , CVAR_SERVERINFO | CVAR_ROM, 0, qfalse  },    { &g_restarted, "g_restarted", "0", CVAR_ROM, 0, qfalse  },    { &g_lockTeamsAtStart, "g_lockTeamsAtStart", "0", CVAR_ROM, 0, qfalse  },    { NULL, "sv_mapname", "", CVAR_SERVERINFO | CVAR_ROM, 0, qfalse  }, @@ -384,7 +383,8 @@ static cvarTable_t   gameCvarTable[ ] =    { &g_MinAlienExtraBuildPoints, "g_MinAlienExtraBuildPoints", "-800", CVAR_ARCHIVE, 0, qfalse },    { &g_MaxAlienExtraBuildPoints, "g_MaxAlienExtraBuildPoints", "800", CVAR_ARCHIVE, 0, qfalse },    { &g_MinHumanExtraBuildPoints, "g_MinHumanExtraBuildPoints", "-800", CVAR_ARCHIVE, 0, qfalse }, -  { &g_MaxHumanExtraBuildPoints, "g_MaxHumanExtraBuildPoints", "800", CVAR_ARCHIVE, 0, qfalse } +  { &g_MaxHumanExtraBuildPoints, "g_MaxHumanExtraBuildPoints", "800", CVAR_ARCHIVE, 0, qfalse }, +  { &g_BuildingCreditsFactor, "g_BuildingCreditsFactor", "0.25", CVAR_ARCHIVE, 0, qfalse }  };  static int gameCvarTableSize = sizeof( gameCvarTable ) / sizeof( gameCvarTable[ 0 ] ); @@ -651,7 +651,7 @@ void G_InitGame( int levelTime, int randomSeed, int restart )    G_Printf( "------- Game Initialization -------\n" );    G_Printf( "gamename: %s\n", GAME_VERSION );    G_Printf( "gamedate: %s\n", __DATE__ ); -  G_Printf( "EDGE VERSION: %s\n", EDGE_MOD_VERSION ); +  G_Printf( "New EDGE version: %s\n", NEWEDGE_MOD_VERSION );    BG_InitMemory( );    // set some level globals @@ -664,7 +664,7 @@ void G_InitGame( int levelTime, int randomSeed, int restart )    level.humanRewardScore = level.alienRewardScore = 0.0f;    level.alienNoBPFlashTime = level.humanNoBPFlashTime = -1;    trap_Cvar_Set( "g_version", G_MOD_VERSION ); -  trap_Cvar_Set( "edge_version", EDGE_MOD_VERSION ); +  trap_Cvar_Set( "newedge_version", NEWEDGE_MOD_VERSION );    if( g_logFile.string[ 0 ] )    {      if( g_logFileSync.integer ) diff --git a/src/game/g_svcmds.c b/src/game/g_svcmds.c index a54a9ad..c9dd825 100644 --- a/src/game/g_svcmds.c +++ b/src/game/g_svcmds.c @@ -515,8 +515,6 @@ static void Svcmd_MessageWrapper( void )    if( !Q_stricmp( cmd, "a" ) )      Cmd_AdminMessage_f( NULL ); -  else if( !Q_stricmp( cmd, "m" ) ) -    Cmd_PrivateMessage_f( NULL );    else if( !Q_stricmp( cmd, "say" ) )      G_Say( NULL, SAY_ALL, ConcatArgs( 1 ) );    else if( !Q_stricmp( cmd, "chat" ) ) @@ -649,7 +647,6 @@ struct svcmd    { "listmaps", qtrue, Svcmd_ListMapsWrapper },    { "listemoticons", qtrue, Svcmd_ListEmoticonsWrapper },    { "loadcensors", qfalse, G_LoadCensors }, -  { "m", qtrue, Svcmd_MessageWrapper },    { "maplog", qtrue, Svcmd_MapLogWrapper },    { "mapRotation", qfalse, Svcmd_MapRotation_f },    { "pr", qfalse, Svcmd_Pr_f }, diff --git a/src/game/newedge_version.h b/src/game/newedge_version.h new file mode 100644 index 0000000..39ca7bc --- /dev/null +++ b/src/game/newedge_version.h @@ -0,0 +1,3 @@ +#ifndef NEWEDGE_MOD_VERSION +#define NEWEDGE_MOD_VERSION "7.7b" +#endif diff --git a/src/tools/lcc/lburg/gram.c b/src/tools/lcc/lburg/gram.c new file mode 100644 index 0000000..f6ee9f9 --- /dev/null +++ b/src/tools/lcc/lburg/gram.c @@ -0,0 +1,1686 @@ +/* A Bison parser, made by GNU Bison 3.0.4.  */ + +/* Bison implementation for Yacc-like parsers in C + +   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + +   This program is free software: you can redistribute it and/or modify +   it under the terms of the GNU General Public License as published by +   the Free Software Foundation, either version 3 of the License, or +   (at your option) any later version. + +   This program is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +   GNU General Public License for more details. + +   You should have received a copy of the GNU General Public License +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ + +/* As a special exception, you may create a larger work that contains +   part or all of the Bison parser skeleton and distribute that work +   under terms of your choice, so long as that work isn't itself a +   parser generator using the skeleton or a modified version thereof +   as a parser skeleton.  Alternatively, if you modify or redistribute +   the parser skeleton itself, you may (at your option) remove this +   special exception, which will cause the skeleton and the resulting +   Bison output files to be licensed under the GNU General Public +   License without this special exception. + +   This special exception was added by the Free Software Foundation in +   version 2.2 of Bison.  */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by +   simplifying the original so-called "semantic" parser.  */ + +/* All symbols defined below should begin with yy or YY, to avoid +   infringing on user name space.  This should be done even for local +   variables, as they might otherwise be expanded by user macros. +   There are some unavoidable exceptions within include files to +   define necessary library symbols; they are noted "INFRINGES ON +   USER NAME SPACE" below.  */ + +/* Identify Bison output.  */ +#define YYBISON 1 + +/* Bison version.  */ +#define YYBISON_VERSION "3.0.4" + +/* Skeleton name.  */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers.  */ +#define YYPURE 0 + +/* Push parsers.  */ +#define YYPUSH 0 + +/* Pull parsers.  */ +#define YYPULL 1 + + + + +/* Copy the first part of user declarations.  */ +#line 1 "src/tools/lcc/lburg/gram.y" /* yacc.c:339  */ + +#include <stdio.h> +#include "lburg.h" +static char rcsid[] = "$Id: gram.y 145 2001-10-17 21:53:10Z timo $"; +/*lint -e616 -e527 -e652 -esym(552,yynerrs) -esym(563,yynewstate,yyerrlab) */ +static int yylineno = 0; + +#line 74 "y.tab.c" /* yacc.c:339  */ + +# ifndef YY_NULLPTR +#  if defined __cplusplus && 201103L <= __cplusplus +#   define YY_NULLPTR nullptr +#  else +#   define YY_NULLPTR 0 +#  endif +# endif + +/* Enabling verbose error messages.  */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + + +/* Debug traces.  */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Token type.  */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE +  enum yytokentype +  { +    TERMINAL = 258, +    START = 259, +    PPERCENT = 260, +    ID = 261, +    TEMPLATE = 262, +    CODE = 263, +    INT = 264 +  }; +#endif +/* Tokens.  */ +#define TERMINAL 258 +#define START 259 +#define PPERCENT 260 +#define ID 261 +#define TEMPLATE 262 +#define CODE 263 +#define INT 264 + +/* Value type.  */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED + +union YYSTYPE +{ +#line 8 "src/tools/lcc/lburg/gram.y" /* yacc.c:355  */ + +	int n; +	char *string; +	Tree tree; + +#line 135 "y.tab.c" /* yacc.c:355  */ +}; + +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE yylval; + +int yyparse (void); + + + +/* Copy the second part of user declarations.  */ + +#line 152 "y.tab.c" /* yacc.c:358  */ + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +#  define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +#  define YYSIZE_T size_t +# elif ! defined YYSIZE_T +#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */ +#  define YYSIZE_T size_t +# else +#  define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +#  if ENABLE_NLS +#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */ +#   define YY_(Msgid) dgettext ("bison-runtime", Msgid) +#  endif +# endif +# ifndef YY_ +#  define YY_(Msgid) Msgid +# endif +#endif + +#ifndef YY_ATTRIBUTE +# if (defined __GNUC__                                               \ +      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \ +     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +#  define YY_ATTRIBUTE(Spec) __attribute__(Spec) +# else +#  define YY_ATTRIBUTE(Spec) /* empty */ +# endif +#endif + +#ifndef YY_ATTRIBUTE_PURE +# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__)) +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +#endif + +#if !defined _Noreturn \ +     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) +# if defined _MSC_VER && 1200 <= _MSC_VER +#  define _Noreturn __declspec (noreturn) +# else +#  define _Noreturn YY_ATTRIBUTE ((__noreturn__)) +# endif +#endif + +/* Suppress unused-variable warnings by "using" E.  */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(E) ((void) (E)) +#else +# define YYUSE(E) /* empty */ +#endif + +#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized.  */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ +    _Pragma ("GCC diagnostic push") \ +    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ +    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ +    _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols.  */ + +# ifdef YYSTACK_USE_ALLOCA +#  if YYSTACK_USE_ALLOCA +#   ifdef __GNUC__ +#    define YYSTACK_ALLOC __builtin_alloca +#   elif defined __BUILTIN_VA_ARG_INCR +#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */ +#   elif defined _AIX +#    define YYSTACK_ALLOC __alloca +#   elif defined _MSC_VER +#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */ +#    define alloca _alloca +#   else +#    define YYSTACK_ALLOC alloca +#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */ +#     ifndef EXIT_SUCCESS +#      define EXIT_SUCCESS 0 +#     endif +#    endif +#   endif +#  endif +# endif + +# ifdef YYSTACK_ALLOC +   /* Pacify GCC's 'empty if-body' warning.  */ +#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +#  ifndef YYSTACK_ALLOC_MAXIMUM +    /* The OS might guarantee only one guard page at the bottom of the stack, +       and a page size can be as small as 4096 bytes.  So we cannot safely +       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number +       to allow for a few compiler-allocated temporary stack slots.  */ +#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +#  endif +# else +#  define YYSTACK_ALLOC YYMALLOC +#  define YYSTACK_FREE YYFREE +#  ifndef YYSTACK_ALLOC_MAXIMUM +#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +#  endif +#  if (defined __cplusplus && ! defined EXIT_SUCCESS \ +       && ! ((defined YYMALLOC || defined malloc) \ +             && (defined YYFREE || defined free))) +#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +#   ifndef EXIT_SUCCESS +#    define EXIT_SUCCESS 0 +#   endif +#  endif +#  ifndef YYMALLOC +#   define YYMALLOC malloc +#   if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +#   endif +#  endif +#  ifndef YYFREE +#   define YYFREE free +#   if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +#   endif +#  endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ +     && (! defined __cplusplus \ +         || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member.  */ +union yyalloc +{ +  yytype_int16 yyss_alloc; +  YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next.  */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with +   N elements.  */ +# define YYSTACK_BYTES(N) \ +     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ +      + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one.  The +   local variables YYSIZE and YYSTACKSIZE give the old and new number of +   elements in the stack, and YYPTR gives the new location of the +   stack.  Advance YYPTR to a properly aligned location for the next +   stack.  */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \ +    do                                                                  \ +      {                                                                 \ +        YYSIZE_T yynewbytes;                                            \ +        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \ +        Stack = &yyptr->Stack_alloc;                                    \ +        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ +        yyptr += yynewbytes / sizeof (*yyptr);                          \ +      }                                                                 \ +    while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST.  The source and destination do +   not overlap.  */ +# ifndef YYCOPY +#  if defined __GNUC__ && 1 < __GNUC__ +#   define YYCOPY(Dst, Src, Count) \ +      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +#  else +#   define YYCOPY(Dst, Src, Count)              \ +      do                                        \ +        {                                       \ +          YYSIZE_T yyi;                         \ +          for (yyi = 0; yyi < (Count); yyi++)   \ +            (Dst)[yyi] = (Src)[yyi];            \ +        }                                       \ +      while (0) +#  endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state.  */ +#define YYFINAL  3 +/* YYLAST -- Last index in YYTABLE.  */ +#define YYLAST   35 + +/* YYNTOKENS -- Number of terminals.  */ +#define YYNTOKENS  16 +/* YYNNTS -- Number of nonterminals.  */ +#define YYNNTS  9 +/* YYNRULES -- Number of rules.  */ +#define YYNRULES  20 +/* YYNSTATES -- Number of states.  */ +#define YYNSTATES  37 + +/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned +   by yylex, with out-of-bounds checking.  */ +#define YYUNDEFTOK  2 +#define YYMAXUTOK   264 + +#define YYTRANSLATE(YYX)                                                \ +  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM +   as returned by yylex, without out-of-bounds checking.  */ +static const yytype_uint8 yytranslate[] = +{ +       0,     2,     2,     2,     2,     2,     2,     2,     2,     2, +      10,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +      13,    14,     2,     2,    15,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,    12,     2, +       2,    11,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     2,     2,     2,     2, +       2,     2,     2,     2,     2,     2,     1,     2,     3,     4, +       5,     6,     7,     8,     9 +}; + +#if YYDEBUG +  /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */ +static const yytype_uint8 yyrline[] = +{ +       0,    22,    22,    23,    26,    27,    30,    31,    35,    36, +      39,    40,    43,    44,    45,    46,    49,    52,    53,    54, +      57 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 0 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. +   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */ +static const char *const yytname[] = +{ +  "$end", "error", "$undefined", "TERMINAL", "START", "PPERCENT", "ID", +  "TEMPLATE", "CODE", "INT", "'\\n'", "'='", "':'", "'('", "')'", "','", +  "$accept", "spec", "decls", "decl", "blist", "rules", "nonterm", "tree", +  "cost", YY_NULLPTR +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[NUM] -- (External) token number corresponding to the +   (internal) symbol number NUM (which must be that of a token).  */ +static const yytype_uint16 yytoknum[] = +{ +       0,   256,   257,   258,   259,   260,   261,   262,   263,   264, +      10,    61,    58,    40,    41,    44 +}; +# endif + +#define YYPACT_NINF -26 + +#define yypact_value_is_default(Yystate) \ +  (!!((Yystate) == (-26))) + +#define YYTABLE_NINF -4 + +#define yytable_value_is_error(Yytable_value) \ +  0 + +  /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing +     STATE-NUM.  */ +static const yytype_int8 yypact[] = +{ +     -26,    11,     0,   -26,     5,   -26,     8,   -26,   -26,   -26, +     -26,     3,   -26,     7,     6,     9,   -26,   -26,    12,   -26, +      13,    14,   -26,    15,   -26,    16,    17,    15,    18,     4, +     -26,    20,   -26,    15,   -26,    19,   -26 +}; + +  /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. +     Performed when YYTABLE does not specify something else to do.  Zero +     means the default is an error.  */ +static const yytype_uint8 yydefact[] = +{ +       4,     0,     0,     1,     0,    10,     0,    12,     8,     5, +       9,     0,    16,     0,     0,     0,     6,     7,     0,    14, +       0,     0,    15,     0,    11,    17,     0,     0,     0,     0, +      20,     0,    18,     0,    13,     0,    19 +}; + +  /* YYPGOTO[NTERM-NUM].  */ +static const yytype_int8 yypgoto[] = +{ +     -26,   -26,   -26,   -26,   -26,   -26,    21,   -25,   -26 +}; + +  /* YYDEFGOTO[NTERM-NUM].  */ +static const yytype_int8 yydefgoto[] = +{ +      -1,     1,     2,     9,    11,    14,    13,    26,    31 +}; + +  /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If +     positive, shift that token.  If negative, reduce the rule whose +     number is the opposite.  If YYTABLE_NINF, syntax error.  */ +static const yytype_int8 yytable[] = +{ +      -3,     4,    29,     5,     6,     7,    -2,    18,    35,    15, +       8,     3,    12,    16,    12,    10,    19,    17,    32,    33, +      21,    25,    22,    24,    28,    23,    30,     0,     0,    27, +      34,     0,     0,    36,     0,    20 +}; + +static const yytype_int8 yycheck[] = +{ +       0,     1,    27,     3,     4,     5,     0,     1,    33,     6, +      10,     0,     6,    10,     6,    10,    10,    10,    14,    15, +      11,     6,    10,     9,     7,    12,     8,    -1,    -1,    13, +      10,    -1,    -1,    14,    -1,    14 +}; + +  /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing +     symbol of state STATE-NUM.  */ +static const yytype_uint8 yystos[] = +{ +       0,    17,    18,     0,     1,     3,     4,     5,    10,    19, +      10,    20,     6,    22,    21,     6,    10,    10,     1,    10, +      22,    11,    10,    12,     9,     6,    23,    13,     7,    23, +       8,    24,    14,    15,    10,    23,    14 +}; + +  /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */ +static const yytype_uint8 yyr1[] = +{ +       0,    16,    17,    17,    18,    18,    19,    19,    19,    19, +      20,    20,    21,    21,    21,    21,    22,    23,    23,    23, +      24 +}; + +  /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */ +static const yytype_uint8 yyr2[] = +{ +       0,     2,     3,     1,     0,     2,     3,     3,     1,     2, +       0,     4,     0,     7,     2,     3,     1,     1,     4,     6, +       1 +}; + + +#define yyerrok         (yyerrstatus = 0) +#define yyclearin       (yychar = YYEMPTY) +#define YYEMPTY         (-2) +#define YYEOF           0 + +#define YYACCEPT        goto yyacceptlab +#define YYABORT         goto yyabortlab +#define YYERROR         goto yyerrorlab + + +#define YYRECOVERING()  (!!yyerrstatus) + +#define YYBACKUP(Token, Value)                                  \ +do                                                              \ +  if (yychar == YYEMPTY)                                        \ +    {                                                           \ +      yychar = (Token);                                         \ +      yylval = (Value);                                         \ +      YYPOPSTACK (yylen);                                       \ +      yystate = *yyssp;                                         \ +      goto yybackup;                                            \ +    }                                                           \ +  else                                                          \ +    {                                                           \ +      yyerror (YY_("syntax error: cannot back up")); \ +      YYERROR;                                                  \ +    }                                                           \ +while (0) + +/* Error token number */ +#define YYTERROR        1 +#define YYERRCODE       256 + + + +/* Enable debugging if requested.  */ +#if YYDEBUG + +# ifndef YYFPRINTF +#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */ +#  define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args)                        \ +do {                                            \ +  if (yydebug)                                  \ +    YYFPRINTF Args;                             \ +} while (0) + +/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \ +do {                                                                      \ +  if (yydebug)                                                            \ +    {                                                                     \ +      YYFPRINTF (stderr, "%s ", Title);                                   \ +      yy_symbol_print (stderr,                                            \ +                  Type, Value); \ +      YYFPRINTF (stderr, "\n");                                           \ +    }                                                                     \ +} while (0) + + +/*----------------------------------------. +| Print this symbol's value on YYOUTPUT.  | +`----------------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +{ +  FILE *yyo = yyoutput; +  YYUSE (yyo); +  if (!yyvaluep) +    return; +# ifdef YYPRINT +  if (yytype < YYNTOKENS) +    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif +  YYUSE (yytype); +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT.  | +`--------------------------------*/ + +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +{ +  YYFPRINTF (yyoutput, "%s %s (", +             yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + +  yy_symbol_value_print (yyoutput, yytype, yyvaluep); +  YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included).                                                   | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +{ +  YYFPRINTF (stderr, "Stack now"); +  for (; yybottom <= yytop; yybottom++) +    { +      int yybot = *yybottom; +      YYFPRINTF (stderr, " %d", yybot); +    } +  YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top)                            \ +do {                                                            \ +  if (yydebug)                                                  \ +    yy_stack_print ((Bottom), (Top));                           \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced.  | +`------------------------------------------------*/ + +static void +yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) +{ +  unsigned long int yylno = yyrline[yyrule]; +  int yynrhs = yyr2[yyrule]; +  int yyi; +  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", +             yyrule - 1, yylno); +  /* The symbols being reduced.  */ +  for (yyi = 0; yyi < yynrhs; yyi++) +    { +      YYFPRINTF (stderr, "   $%d = ", yyi + 1); +      yy_symbol_print (stderr, +                       yystos[yyssp[yyi + 1 - yynrhs]], +                       &(yyvsp[(yyi + 1) - (yynrhs)]) +                                              ); +      YYFPRINTF (stderr, "\n"); +    } +} + +# define YY_REDUCE_PRINT(Rule)          \ +do {                                    \ +  if (yydebug)                          \ +    yy_reduce_print (yyssp, yyvsp, Rule); \ +} while (0) + +/* Nonzero means print parse trace.  It is left uninitialized so that +   multiple parsers can coexist.  */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks.  */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only +   if the built-in stack extension method is used). + +   Do not make this value too large; the results are undefined if +   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) +   evaluated with infinite-precision integer arithmetic.  */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +#  if defined __GLIBC__ && defined _STRING_H +#   define yystrlen strlen +#  else +/* Return the length of YYSTR.  */ +static YYSIZE_T +yystrlen (const char *yystr) +{ +  YYSIZE_T yylen; +  for (yylen = 0; yystr[yylen]; yylen++) +    continue; +  return yylen; +} +#  endif +# endif + +# ifndef yystpcpy +#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +#   define yystpcpy stpcpy +#  else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in +   YYDEST.  */ +static char * +yystpcpy (char *yydest, const char *yysrc) +{ +  char *yyd = yydest; +  const char *yys = yysrc; + +  while ((*yyd++ = *yys++) != '\0') +    continue; + +  return yyd - 1; +} +#  endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary +   quotes and backslashes, so that it's suitable for yyerror.  The +   heuristic is that double-quoting is unnecessary unless the string +   contains an apostrophe, a comma, or backslash (other than +   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is +   null, do not copy; instead, return the length of what the result +   would have been.  */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ +  if (*yystr == '"') +    { +      YYSIZE_T yyn = 0; +      char const *yyp = yystr; + +      for (;;) +        switch (*++yyp) +          { +          case '\'': +          case ',': +            goto do_not_strip_quotes; + +          case '\\': +            if (*++yyp != '\\') +              goto do_not_strip_quotes; +            /* Fall through.  */ +          default: +            if (yyres) +              yyres[yyn] = *yyp; +            yyn++; +            break; + +          case '"': +            if (yyres) +              yyres[yyn] = '\0'; +            return yyn; +          } +    do_not_strip_quotes: ; +    } + +  if (! yyres) +    return yystrlen (yystr); + +  return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message +   about the unexpected token YYTOKEN for the state stack whose top is +   YYSSP. + +   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is +   not large enough to hold the message.  In that case, also set +   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the +   required number of bytes is too large to store.  */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, +                yytype_int16 *yyssp, int yytoken) +{ +  YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); +  YYSIZE_T yysize = yysize0; +  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; +  /* Internationalized format string. */ +  const char *yyformat = YY_NULLPTR; +  /* Arguments of yyformat. */ +  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; +  /* Number of reported tokens (one for the "unexpected", one per +     "expected"). */ +  int yycount = 0; + +  /* There are many possibilities here to consider: +     - If this state is a consistent state with a default action, then +       the only way this function was invoked is if the default action +       is an error action.  In that case, don't check for expected +       tokens because there are none. +     - The only way there can be no lookahead present (in yychar) is if +       this state is a consistent state with a default action.  Thus, +       detecting the absence of a lookahead is sufficient to determine +       that there is no unexpected or expected token to report.  In that +       case, just report a simple "syntax error". +     - Don't assume there isn't a lookahead just because this state is a +       consistent state with a default action.  There might have been a +       previous inconsistent state, consistent state with a non-default +       action, or user semantic action that manipulated yychar. +     - Of course, the expected token list depends on states to have +       correct lookahead information, and it depends on the parser not +       to perform extra reductions after fetching a lookahead from the +       scanner and before detecting a syntax error.  Thus, state merging +       (from LALR or IELR) and default reductions corrupt the expected +       token list.  However, the list is correct for canonical LR with +       one exception: it will still contain any token that will not be +       accepted due to an error action in a later state. +  */ +  if (yytoken != YYEMPTY) +    { +      int yyn = yypact[*yyssp]; +      yyarg[yycount++] = yytname[yytoken]; +      if (!yypact_value_is_default (yyn)) +        { +          /* Start YYX at -YYN if negative to avoid negative indexes in +             YYCHECK.  In other words, skip the first -YYN actions for +             this state because they are default actions.  */ +          int yyxbegin = yyn < 0 ? -yyn : 0; +          /* Stay within bounds of both yycheck and yytname.  */ +          int yychecklim = YYLAST - yyn + 1; +          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; +          int yyx; + +          for (yyx = yyxbegin; yyx < yyxend; ++yyx) +            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR +                && !yytable_value_is_error (yytable[yyx + yyn])) +              { +                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) +                  { +                    yycount = 1; +                    yysize = yysize0; +                    break; +                  } +                yyarg[yycount++] = yytname[yyx]; +                { +                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); +                  if (! (yysize <= yysize1 +                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) +                    return 2; +                  yysize = yysize1; +                } +              } +        } +    } + +  switch (yycount) +    { +# define YYCASE_(N, S)                      \ +      case N:                               \ +        yyformat = S;                       \ +      break +      YYCASE_(0, YY_("syntax error")); +      YYCASE_(1, YY_("syntax error, unexpected %s")); +      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); +      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); +      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); +      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ +    } + +  { +    YYSIZE_T yysize1 = yysize + yystrlen (yyformat); +    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) +      return 2; +    yysize = yysize1; +  } + +  if (*yymsg_alloc < yysize) +    { +      *yymsg_alloc = 2 * yysize; +      if (! (yysize <= *yymsg_alloc +             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) +        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; +      return 1; +    } + +  /* Avoid sprintf, as that infringes on the user's name space. +     Don't have undefined behavior even if the translation +     produced a string with the wrong number of "%s"s.  */ +  { +    char *yyp = *yymsg; +    int yyi = 0; +    while ((*yyp = *yyformat) != '\0') +      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) +        { +          yyp += yytnamerr (yyp, yyarg[yyi++]); +          yyformat += 2; +        } +      else +        { +          yyp++; +          yyformat++; +        } +  } +  return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol.  | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +{ +  YYUSE (yyvaluep); +  if (!yymsg) +    yymsg = "Deleting"; +  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + +  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +  YYUSE (yytype); +  YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + + + +/* The lookahead symbol.  */ +int yychar; + +/* The semantic value of the lookahead symbol.  */ +YYSTYPE yylval; +/* Number of syntax errors so far.  */ +int yynerrs; + + +/*----------. +| yyparse.  | +`----------*/ + +int +yyparse (void) +{ +    int yystate; +    /* Number of tokens to shift before error messages enabled.  */ +    int yyerrstatus; + +    /* The stacks and their tools: +       'yyss': related to states. +       'yyvs': related to semantic values. + +       Refer to the stacks through separate pointers, to allow yyoverflow +       to reallocate them elsewhere.  */ + +    /* The state stack.  */ +    yytype_int16 yyssa[YYINITDEPTH]; +    yytype_int16 *yyss; +    yytype_int16 *yyssp; + +    /* The semantic value stack.  */ +    YYSTYPE yyvsa[YYINITDEPTH]; +    YYSTYPE *yyvs; +    YYSTYPE *yyvsp; + +    YYSIZE_T yystacksize; + +  int yyn; +  int yyresult; +  /* Lookahead token as an internal (translated) token number.  */ +  int yytoken = 0; +  /* The variables used to return semantic value and location from the +     action routines.  */ +  YYSTYPE yyval; + +#if YYERROR_VERBOSE +  /* Buffer for error messages, and its allocated size.  */ +  char yymsgbuf[128]; +  char *yymsg = yymsgbuf; +  YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N)) + +  /* The number of symbols on the RHS of the reduced rule. +     Keep to zero when no symbol should be popped.  */ +  int yylen = 0; + +  yyssp = yyss = yyssa; +  yyvsp = yyvs = yyvsa; +  yystacksize = YYINITDEPTH; + +  YYDPRINTF ((stderr, "Starting parse\n")); + +  yystate = 0; +  yyerrstatus = 0; +  yynerrs = 0; +  yychar = YYEMPTY; /* Cause a token to be read.  */ +  goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate.  | +`------------------------------------------------------------*/ + yynewstate: +  /* In all cases, when you get here, the value and location stacks +     have just been pushed.  So pushing a state here evens the stacks.  */ +  yyssp++; + + yysetstate: +  *yyssp = yystate; + +  if (yyss + yystacksize - 1 <= yyssp) +    { +      /* Get the current used size of the three stacks, in elements.  */ +      YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow +      { +        /* Give user a chance to reallocate the stack.  Use copies of +           these so that the &'s don't force the real ones into +           memory.  */ +        YYSTYPE *yyvs1 = yyvs; +        yytype_int16 *yyss1 = yyss; + +        /* Each stack pointer address is followed by the size of the +           data in use in that stack, in bytes.  This used to be a +           conditional around just the two extra args, but that might +           be undefined if yyoverflow is a macro.  */ +        yyoverflow (YY_("memory exhausted"), +                    &yyss1, yysize * sizeof (*yyssp), +                    &yyvs1, yysize * sizeof (*yyvsp), +                    &yystacksize); + +        yyss = yyss1; +        yyvs = yyvs1; +      } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE +      goto yyexhaustedlab; +# else +      /* Extend the stack our own way.  */ +      if (YYMAXDEPTH <= yystacksize) +        goto yyexhaustedlab; +      yystacksize *= 2; +      if (YYMAXDEPTH < yystacksize) +        yystacksize = YYMAXDEPTH; + +      { +        yytype_int16 *yyss1 = yyss; +        union yyalloc *yyptr = +          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); +        if (! yyptr) +          goto yyexhaustedlab; +        YYSTACK_RELOCATE (yyss_alloc, yyss); +        YYSTACK_RELOCATE (yyvs_alloc, yyvs); +#  undef YYSTACK_RELOCATE +        if (yyss1 != yyssa) +          YYSTACK_FREE (yyss1); +      } +# endif +#endif /* no yyoverflow */ + +      yyssp = yyss + yysize - 1; +      yyvsp = yyvs + yysize - 1; + +      YYDPRINTF ((stderr, "Stack size increased to %lu\n", +                  (unsigned long int) yystacksize)); + +      if (yyss + yystacksize - 1 <= yyssp) +        YYABORT; +    } + +  YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + +  if (yystate == YYFINAL) +    YYACCEPT; + +  goto yybackup; + +/*-----------. +| yybackup.  | +`-----------*/ +yybackup: + +  /* Do appropriate processing given the current state.  Read a +     lookahead token if we need one and don't already have one.  */ + +  /* First try to decide what to do without reference to lookahead token.  */ +  yyn = yypact[yystate]; +  if (yypact_value_is_default (yyn)) +    goto yydefault; + +  /* Not known => get a lookahead token if don't already have one.  */ + +  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */ +  if (yychar == YYEMPTY) +    { +      YYDPRINTF ((stderr, "Reading a token: ")); +      yychar = yylex (); +    } + +  if (yychar <= YYEOF) +    { +      yychar = yytoken = YYEOF; +      YYDPRINTF ((stderr, "Now at end of input.\n")); +    } +  else +    { +      yytoken = YYTRANSLATE (yychar); +      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); +    } + +  /* If the proper action on seeing token YYTOKEN is to reduce or to +     detect an error, take that action.  */ +  yyn += yytoken; +  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) +    goto yydefault; +  yyn = yytable[yyn]; +  if (yyn <= 0) +    { +      if (yytable_value_is_error (yyn)) +        goto yyerrlab; +      yyn = -yyn; +      goto yyreduce; +    } + +  /* Count tokens shifted since error; after three, turn off error +     status.  */ +  if (yyerrstatus) +    yyerrstatus--; + +  /* Shift the lookahead token.  */ +  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + +  /* Discard the shifted token.  */ +  yychar = YYEMPTY; + +  yystate = yyn; +  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +  *++yyvsp = yylval; +  YY_IGNORE_MAYBE_UNINITIALIZED_END + +  goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state.  | +`-----------------------------------------------------------*/ +yydefault: +  yyn = yydefact[yystate]; +  if (yyn == 0) +    goto yyerrlab; +  goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction.  | +`-----------------------------*/ +yyreduce: +  /* yyn is the number of a rule to reduce with.  */ +  yylen = yyr2[yyn]; + +  /* If YYLEN is nonzero, implement the default value of the action: +     '$$ = $1'. + +     Otherwise, the following line sets YYVAL to garbage. +     This behavior is undocumented and Bison +     users should not rely upon it.  Assigning to YYVAL +     unconditionally makes the parser a bit smaller, and it avoids a +     GCC warning that YYVAL may be used uninitialized.  */ +  yyval = yyvsp[1-yylen]; + + +  YY_REDUCE_PRINT (yyn); +  switch (yyn) +    { +        case 2: +#line 22 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646  */ +    { yylineno = 0; } +#line 1242 "y.tab.c" /* yacc.c:1646  */ +    break; + +  case 3: +#line 23 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646  */ +    { yylineno = 0; } +#line 1248 "y.tab.c" /* yacc.c:1646  */ +    break; + +  case 7: +#line 31 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646  */ +    { +		if (nonterm((yyvsp[-1].string))->number != 1) +			yyerror("redeclaration of the start symbol\n"); +		} +#line 1257 "y.tab.c" /* yacc.c:1646  */ +    break; + +  case 9: +#line 36 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646  */ +    { yyerrok; } +#line 1263 "y.tab.c" /* yacc.c:1646  */ +    break; + +  case 11: +#line 40 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646  */ +    { term((yyvsp[-2].string), (yyvsp[0].n)); } +#line 1269 "y.tab.c" /* yacc.c:1646  */ +    break; + +  case 13: +#line 44 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646  */ +    { rule((yyvsp[-5].string), (yyvsp[-3].tree), (yyvsp[-2].string), (yyvsp[-1].string)); } +#line 1275 "y.tab.c" /* yacc.c:1646  */ +    break; + +  case 15: +#line 46 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646  */ +    { yyerrok; } +#line 1281 "y.tab.c" /* yacc.c:1646  */ +    break; + +  case 16: +#line 49 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646  */ +    { nonterm((yyval.string) = (yyvsp[0].string)); } +#line 1287 "y.tab.c" /* yacc.c:1646  */ +    break; + +  case 17: +#line 52 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646  */ +    { (yyval.tree) = tree((yyvsp[0].string),  0,  0); } +#line 1293 "y.tab.c" /* yacc.c:1646  */ +    break; + +  case 18: +#line 53 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646  */ +    { (yyval.tree) = tree((yyvsp[-3].string), (yyvsp[-1].tree),  0); } +#line 1299 "y.tab.c" /* yacc.c:1646  */ +    break; + +  case 19: +#line 54 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646  */ +    { (yyval.tree) = tree((yyvsp[-5].string), (yyvsp[-3].tree), (yyvsp[-1].tree)); } +#line 1305 "y.tab.c" /* yacc.c:1646  */ +    break; + +  case 20: +#line 57 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646  */ +    { if (*(yyvsp[0].string) == 0) (yyval.string) = "0"; } +#line 1311 "y.tab.c" /* yacc.c:1646  */ +    break; + + +#line 1315 "y.tab.c" /* yacc.c:1646  */ +      default: break; +    } +  /* User semantic actions sometimes alter yychar, and that requires +     that yytoken be updated with the new translation.  We take the +     approach of translating immediately before every use of yytoken. +     One alternative is translating here after every semantic action, +     but that translation would be missed if the semantic action invokes +     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or +     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an +     incorrect destructor might then be invoked immediately.  In the +     case of YYERROR or YYBACKUP, subsequent parser actions might lead +     to an incorrect destructor call or verbose syntax error message +     before the lookahead is translated.  */ +  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + +  YYPOPSTACK (yylen); +  yylen = 0; +  YY_STACK_PRINT (yyss, yyssp); + +  *++yyvsp = yyval; + +  /* Now 'shift' the result of the reduction.  Determine what state +     that goes to, based on the state we popped back to and the rule +     number reduced by.  */ + +  yyn = yyr1[yyn]; + +  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; +  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) +    yystate = yytable[yystate]; +  else +    yystate = yydefgoto[yyn - YYNTOKENS]; + +  goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error.  | +`--------------------------------------*/ +yyerrlab: +  /* Make sure we have latest lookahead translation.  See comments at +     user semantic actions for why this is necessary.  */ +  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + +  /* If not already recovering from an error, report this error.  */ +  if (!yyerrstatus) +    { +      ++yynerrs; +#if ! YYERROR_VERBOSE +      yyerror (YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ +                                        yyssp, yytoken) +      { +        char const *yymsgp = YY_("syntax error"); +        int yysyntax_error_status; +        yysyntax_error_status = YYSYNTAX_ERROR; +        if (yysyntax_error_status == 0) +          yymsgp = yymsg; +        else if (yysyntax_error_status == 1) +          { +            if (yymsg != yymsgbuf) +              YYSTACK_FREE (yymsg); +            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); +            if (!yymsg) +              { +                yymsg = yymsgbuf; +                yymsg_alloc = sizeof yymsgbuf; +                yysyntax_error_status = 2; +              } +            else +              { +                yysyntax_error_status = YYSYNTAX_ERROR; +                yymsgp = yymsg; +              } +          } +        yyerror (yymsgp); +        if (yysyntax_error_status == 2) +          goto yyexhaustedlab; +      } +# undef YYSYNTAX_ERROR +#endif +    } + + + +  if (yyerrstatus == 3) +    { +      /* If just tried and failed to reuse lookahead token after an +         error, discard it.  */ + +      if (yychar <= YYEOF) +        { +          /* Return failure if at end of input.  */ +          if (yychar == YYEOF) +            YYABORT; +        } +      else +        { +          yydestruct ("Error: discarding", +                      yytoken, &yylval); +          yychar = YYEMPTY; +        } +    } + +  /* Else will try to reuse lookahead token after shifting the error +     token.  */ +  goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR.  | +`---------------------------------------------------*/ +yyerrorlab: + +  /* Pacify compilers like GCC when the user code never invokes +     YYERROR and the label yyerrorlab therefore never appears in user +     code.  */ +  if (/*CONSTCOND*/ 0) +     goto yyerrorlab; + +  /* Do not reclaim the symbols of the rule whose action triggered +     this YYERROR.  */ +  YYPOPSTACK (yylen); +  yylen = 0; +  YY_STACK_PRINT (yyss, yyssp); +  yystate = *yyssp; +  goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR.  | +`-------------------------------------------------------------*/ +yyerrlab1: +  yyerrstatus = 3;      /* Each real token shifted decrements this.  */ + +  for (;;) +    { +      yyn = yypact[yystate]; +      if (!yypact_value_is_default (yyn)) +        { +          yyn += YYTERROR; +          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) +            { +              yyn = yytable[yyn]; +              if (0 < yyn) +                break; +            } +        } + +      /* Pop the current state because it cannot handle the error token.  */ +      if (yyssp == yyss) +        YYABORT; + + +      yydestruct ("Error: popping", +                  yystos[yystate], yyvsp); +      YYPOPSTACK (1); +      yystate = *yyssp; +      YY_STACK_PRINT (yyss, yyssp); +    } + +  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +  *++yyvsp = yylval; +  YY_IGNORE_MAYBE_UNINITIALIZED_END + + +  /* Shift the error token.  */ +  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + +  yystate = yyn; +  goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here.  | +`-------------------------------------*/ +yyacceptlab: +  yyresult = 0; +  goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here.  | +`-----------------------------------*/ +yyabortlab: +  yyresult = 1; +  goto yyreturn; + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here.  | +`-------------------------------------------------*/ +yyexhaustedlab: +  yyerror (YY_("memory exhausted")); +  yyresult = 2; +  /* Fall through.  */ +#endif + +yyreturn: +  if (yychar != YYEMPTY) +    { +      /* Make sure we have latest lookahead translation.  See comments at +         user semantic actions for why this is necessary.  */ +      yytoken = YYTRANSLATE (yychar); +      yydestruct ("Cleanup: discarding lookahead", +                  yytoken, &yylval); +    } +  /* Do not reclaim the symbols of the rule whose action triggered +     this YYABORT or YYACCEPT.  */ +  YYPOPSTACK (yylen); +  YY_STACK_PRINT (yyss, yyssp); +  while (yyssp != yyss) +    { +      yydestruct ("Cleanup: popping", +                  yystos[*yyssp], yyvsp); +      YYPOPSTACK (1); +    } +#ifndef yyoverflow +  if (yyss != yyssa) +    YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE +  if (yymsg != yymsgbuf) +    YYSTACK_FREE (yymsg); +#endif +  return yyresult; +} +#line 59 "src/tools/lcc/lburg/gram.y" /* yacc.c:1906  */ + +#include <assert.h> +#include <stdarg.h> +#include <ctype.h> +#include <string.h> +#include <limits.h> + +int errcnt = 0; +FILE *infp = NULL; +FILE *outfp = NULL; +static char buf[BUFSIZ], *bp = buf; +static int ppercent = 0; +static int code = 0; + +static int get(void) { +	if (*bp == 0) { +		bp = buf; +		*bp = 0; +		if (fgets(buf, sizeof buf, infp) == NULL) +			return EOF; +		yylineno++; +		while (buf[0] == '%' && buf[1] == '{' && buf[2] == '\n') { +			for (;;) { +				if (fgets(buf, sizeof buf, infp) == NULL) { +					yywarn("unterminated %{...%}\n"); +					return EOF; +				} +				yylineno++; +				if (strcmp(buf, "%}\n") == 0) +					break; +				fputs(buf, outfp); +			} +			if (fgets(buf, sizeof buf, infp) == NULL) +				return EOF; +			yylineno++; +		} +	} +	return *bp++; +} + +void yyerror(char *fmt, ...) { +	va_list ap; + +	va_start(ap, fmt); +	if (yylineno > 0) +		fprintf(stderr, "line %d: ", yylineno); +	vfprintf(stderr, fmt, ap); +	if (fmt[strlen(fmt)-1] != '\n') +		 fprintf(stderr, "\n"); +	errcnt++; +	va_end(ap); +} + +int yylex(void) { +	int c; + +	if (code) { +		char *p; +		bp += strspn(bp, " \t\f"); +		p = strchr(bp, '\n'); +		if (p == NULL) +			p = strchr(bp, '\n'); +		while (p > bp && isspace(p[-1])) +			p--; +		yylval.string = alloc(p - bp + 1); +		strncpy(yylval.string, bp, p - bp); +		yylval.string[p - bp] = 0; +		bp = p; +		code--; +		return CODE; +	} +	while ((c = get()) != EOF) { +		switch (c) { +		case ' ': case '\f': case '\t': +			continue; +		case '\n': +		case '(': case ')': case ',': +		case ':': case '=': +			return c; +		} +		if (c == '%' && *bp == '%') { +			bp++; +			return ppercent++ ? 0 : PPERCENT; +		} else if (c == '%' && strncmp(bp, "term", 4) == 0 +		&& isspace(bp[4])) { +			bp += 4; +			return TERMINAL; +		} else if (c == '%' && strncmp(bp, "start", 5) == 0 +		&& isspace(bp[5])) { +			bp += 5; +			return START; +		} else if (c == '"') { +			char *p = strchr(bp, '"'); +			if (p == NULL) { +				yyerror("missing \" in assembler template\n"); +				p = strchr(bp, '\n'); +				if (p == NULL) +					p = strchr(bp, '\0'); +			} +			assert(p); +			yylval.string = alloc(p - bp + 1); +			strncpy(yylval.string, bp, p - bp); +			yylval.string[p - bp] = 0; +			bp = *p == '"' ? p + 1 : p; +			code++; +			return TEMPLATE; +		} else if (isdigit(c)) { +			int n = 0; +			do { +				int d = c - '0'; +				if (n > (INT_MAX - d)/10) +					yyerror("integer greater than %d\n", INT_MAX); +				else +					n = 10*n + d; +				c = get(); +			} while (c != EOF && isdigit(c)); +			bp--; +			yylval.n = n; +			return INT; +		} else if (isalpha(c)) { +			char *p = bp - 1; +			while (isalpha(*bp) || isdigit(*bp) || *bp == '_') +				bp++; +			yylval.string = alloc(bp - p + 1); +			strncpy(yylval.string, p, bp - p); +			yylval.string[bp - p] = 0; +			return ID; +		} else if (isprint(c)) +			yyerror("invalid character `%c'\n", c); +		else +			yyerror("invalid character `\\%03o'\n", (unsigned char)c); +	} +	return 0; +} + +void yywarn(char *fmt, ...) { +	va_list ap; + +	va_start(ap, fmt); +	if (yylineno > 0) +		fprintf(stderr, "line %d: ", yylineno); +	fprintf(stderr, "warning: "); +	vfprintf(stderr, fmt, ap); +}  | 
