aboutsummaryrefslogtreecommitdiff
path: root/ld/po
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2007-09-17 14:06:03 +0000
committerNick Clifton <nickc@redhat.com>2007-09-17 14:06:03 +0000
commit7f396d02ee5b6f506fa1fd3f78b2283c93fbbe2b (patch)
tree483b05311988f968ee3c2e3b22eecb7addceed48 /ld/po
parent041a1845a91c0ac19e4ec42957dae2f935facff4 (diff)
downloadgdb-7f396d02ee5b6f506fa1fd3f78b2283c93fbbe2b.zip
gdb-7f396d02ee5b6f506fa1fd3f78b2283c93fbbe2b.tar.gz
gdb-7f396d02ee5b6f506fa1fd3f78b2283c93fbbe2b.tar.bz2
Updated Spanish translation
Diffstat (limited to 'ld/po')
-rw-r--r--ld/po/es.po1120
1 files changed, 594 insertions, 526 deletions
diff --git a/ld/po/es.po b/ld/po/es.po
index 64c51a7..ee9212b 100644
--- a/ld/po/es.po
+++ b/ld/po/es.po
@@ -1,13 +1,13 @@
-# Mensajes en español para ld 2.16.93.
-# Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-# Cristian Othón Martínez Vera <cfuga@itam.mx>, 2002, 2003, 2004, 2005, 2006.
+# Mensajes en español para ld 2.17.90.
+# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+# Cristian Othón Martínez Vera <cfuga@itam.mx>, 2002, 2003, 2004, 2005, 2006, 2007.
#
msgid ""
msgstr ""
-"Project-Id-Version: ld 2.16.93\n"
+"Project-Id-Version: ld 2.17.90\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-03-25 18:36+0100\n"
-"PO-Revision-Date: 2006-05-26 16:31-0500\n"
+"POT-Creation-Date: 2007-06-27 16:44+0930\n"
+"PO-Revision-Date: 2007-09-08 09:45-0500\n"
"Last-Translator: Cristian Othón Martínez Vera <cfuga@itam.mx>\n"
"Language-Team: Spanish <es@li.org>\n"
"MIME-Version: 1.0\n"
@@ -17,7 +17,7 @@ msgstr ""
#: emultempl/armcoff.em:72
#, c-format
msgid " --support-old-code Support interworking with old code\n"
-msgstr " --support-old-code Soporte para interoperar con código antiguo\n"
+msgstr " --support-old-code Admite interoperar con código antiguo\n"
#: emultempl/armcoff.em:73
#, c-format
@@ -27,17 +27,17 @@ msgstr " --thumb-entry=<sim> Establece el punto de entrada para el símbolo Thu
#: emultempl/armcoff.em:121
#, c-format
msgid "Errors encountered processing file %s"
-msgstr "Errores encontrados al procesar el fichero %s"
+msgstr "Se encontraron errores al procesar el fichero %s"
-#: emultempl/armcoff.em:190 emultempl/pe.em:1460
+#: emultempl/armcoff.em:189 emultempl/pe.em:1528
msgid "%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"
msgstr "%P: aviso: '--thumb-entry %s' se impone a '-e %s'\n"
-#: emultempl/armcoff.em:195 emultempl/pe.em:1465
+#: emultempl/armcoff.em:194 emultempl/pe.em:1533
msgid "%P: warning: connot find thumb start symbol %s\n"
msgstr "%P: aviso: no se puede encontrar el símbolo de inicio thumb %s\n"
-#: emultempl/pe.em:304
+#: emultempl/pe.em:311
#, c-format
msgid " --base_file <basefile> Generate a base file for relocatable DLLs\n"
msgstr " --base_file <ficherobase> Genera un fichero base para DLLs reubicables\n"
@@ -45,155 +45,155 @@ msgstr " --base_file <ficherobase> Genera un fichero base para DLLs re
# DLL son las siglas en inglés de `Biblioteca de Enlace Dinámico'.
# El problema es que las siglas en español (BED) no están muy extendidas.
# Se dejó `DLL' sin traducir en todas las ocasiones. cfuga
-#: emultempl/pe.em:305
+#: emultempl/pe.em:312
#, c-format
msgid " --dll Set image base to the default for DLLs\n"
msgstr " --dll Establece la imagen base por defecto para las DLLs\n"
-#: emultempl/pe.em:306
+#: emultempl/pe.em:313
#, c-format
msgid " --file-alignment <size> Set file alignment\n"
msgstr " --file-alignment <tamaño> Establece el fichero de alineación\n"
-#: emultempl/pe.em:307
+#: emultempl/pe.em:314
#, c-format
msgid " --heap <size> Set initial size of the heap\n"
msgstr " --heap <tamaño> Establece el tamaño inicial del montón\n"
-#: emultempl/pe.em:308
+#: emultempl/pe.em:315
#, c-format
msgid " --image-base <address> Set start address of the executable\n"
msgstr " --image-base <dirección> Establece la dirección de inicio del ejecutable\n"
-#: emultempl/pe.em:309
+#: emultempl/pe.em:316
#, c-format
msgid " --major-image-version <number> Set version number of the executable\n"
msgstr " --major-image-version <número> Establece el número de versión del ejecutable\n"
-#: emultempl/pe.em:310
+#: emultempl/pe.em:317
#, c-format
msgid " --major-os-version <number> Set minimum required OS version\n"
msgstr " --major-os-version <número> Establece la versión mínima requerida del SO\n"
-#: emultempl/pe.em:311
+#: emultempl/pe.em:318
#, c-format
msgid " --major-subsystem-version <number> Set minimum required OS subsystem version\n"
msgstr " --major-subsystem-version <número> Establece la versión mínima requerida del subsistema del SO\n"
-#: emultempl/pe.em:312
+#: emultempl/pe.em:319
#, c-format
msgid " --minor-image-version <number> Set revision number of the executable\n"
msgstr " --minor-image-version <número> Establece el número de revisión del ejecutable\n"
-#: emultempl/pe.em:313
+#: emultempl/pe.em:320
#, c-format
msgid " --minor-os-version <number> Set minimum required OS revision\n"
msgstr " --minor-os-version <número> Establece la revisión mínima requerida del SO\n"
-#: emultempl/pe.em:314
+#: emultempl/pe.em:321
#, c-format
msgid " --minor-subsystem-version <number> Set minimum required OS subsystem revision\n"
msgstr " --minor-subsystem-version <número> Establece la revisión mínima requerida del subsistema del SO\n"
-#: emultempl/pe.em:315
+#: emultempl/pe.em:322
#, c-format
msgid " --section-alignment <size> Set section alignment\n"
msgstr " --section-alignment <tamaño> Establece la alineación de la sección\n"
-#: emultempl/pe.em:316
+#: emultempl/pe.em:323
#, c-format
msgid " --stack <size> Set size of the initial stack\n"
msgstr " --stack <size> Establece el tamaño de la pila inicial\n"
-#: emultempl/pe.em:317
+#: emultempl/pe.em:324
#, c-format
msgid " --subsystem <name>[:<version>] Set required OS subsystem [& version]\n"
msgstr " --subsystem <nombre>[:<versión>] Establece el subsistema [y versión] requeridos del SO\n"
-#: emultempl/pe.em:318
+#: emultempl/pe.em:325
#, c-format
msgid " --support-old-code Support interworking with old code\n"
-msgstr " --support-old-code Soporte para interoperar con código antiguo\n"
+msgstr " --support-old-code Admite interoperar con código antiguo\n"
-#: emultempl/pe.em:319
+#: emultempl/pe.em:326
#, c-format
msgid " --thumb-entry=<symbol> Set the entry point to be Thumb <symbol>\n"
msgstr " --thumb-entry=<símbolo> Establece el punto de entrada para el símbolo Thumb <símbolo>\n"
-#: emultempl/pe.em:321
+#: emultempl/pe.em:328
#, c-format
msgid " --add-stdcall-alias Export symbols with and without @nn\n"
-msgstr " --add-stdcall-alias Exportar símbolos con y sin @nn\n"
+msgstr " --add-stdcall-alias Exporta símbolos con y sin @nn\n"
-#: emultempl/pe.em:322
+#: emultempl/pe.em:329
#, c-format
msgid " --disable-stdcall-fixup Don't link _sym to _sym@nn\n"
-msgstr " --disable-stdcall-fixup No enlazar _sym con _sym@nn\n"
+msgstr " --disable-stdcall-fixup No enlaza _sym con _sym@nn\n"
-#: emultempl/pe.em:323
+#: emultempl/pe.em:330
#, c-format
msgid " --enable-stdcall-fixup Link _sym to _sym@nn without warnings\n"
-msgstr " --enable-stdcall-fixup Enlazar _sym con _sym@nn sin avisos\n"
+msgstr " --enable-stdcall-fixup Enlaza _sym con _sym@nn sin avisos\n"
-#: emultempl/pe.em:324
+#: emultempl/pe.em:331
#, c-format
msgid " --exclude-symbols sym,sym,... Exclude symbols from automatic export\n"
msgstr " --exclude-symbols sim,sim,... Excluye los símbolos de la exportación automática\n"
-#: emultempl/pe.em:325
+#: emultempl/pe.em:332
#, c-format
msgid " --exclude-libs lib,lib,... Exclude libraries from automatic export\n"
msgstr " --exclude-libs bib,bib,... Excluye las bibliotecas de la exportación automática\n"
-#: emultempl/pe.em:326
+#: emultempl/pe.em:333
#, c-format
msgid " --export-all-symbols Automatically export all globals to DLL\n"
msgstr " --export-all-symbols Exporta automáticamente todos los globales a la DLL\n"
-#: emultempl/pe.em:327
+#: emultempl/pe.em:334
#, c-format
msgid " --kill-at Remove @nn from exported symbols\n"
msgstr " --kill-at Elimina @nn de los símbolos exportados\n"
-#: emultempl/pe.em:328
+#: emultempl/pe.em:335
#, c-format
msgid " --out-implib <file> Generate import library\n"
-msgstr " --out-implib <fichero> Generar una biblioteca de importación\n"
+msgstr " --out-implib <fichero> Genera una biblioteca de importación\n"
-#: emultempl/pe.em:329
+#: emultempl/pe.em:336
#, c-format
msgid " --output-def <file> Generate a .DEF file for the built DLL\n"
-msgstr " --output-def <fichero> Generar un fichero .DEF para la DLL construida\n"
+msgstr " --output-def <fichero> Genera un fichero .DEF para la DLL construida\n"
-#: emultempl/pe.em:330
+#: emultempl/pe.em:337
#, c-format
msgid " --warn-duplicate-exports Warn about duplicate exports.\n"
-msgstr " --warn-duplicate-exports Avisar sobre exportaciones duplicadas.\n"
+msgstr " --warn-duplicate-exports Avisa sobre exportaciones duplicadas.\n"
-#: emultempl/pe.em:331
+#: emultempl/pe.em:338
#, c-format
msgid ""
" --compat-implib Create backward compatible import libs;\n"
" create __imp_<SYMBOL> as well.\n"
msgstr ""
-" --compat-implib Crear bibliotecas de importación compatibles hacia atrás;\n"
-" cerar además __imp_<SÍMBOLO>.\n"
+" --compat-implib Crea bibliotecas de importación compatibles hacia atrás;\n"
+" crea además __imp_<SÍMBOLO>.\n"
-#: emultempl/pe.em:333
+#: emultempl/pe.em:340
#, c-format
msgid ""
" --enable-auto-image-base Automatically choose image base for DLLs\n"
" unless user specifies one\n"
msgstr ""
-" --enable-auto-image-base Escoger automáticamente la imagen base para las DLLs\n"
+" --enable-auto-image-base Escoge automáticamente la imagen base para las DLLs\n"
" a menos que el usuario especifique una\n"
-#: emultempl/pe.em:335
+#: emultempl/pe.em:342
#, c-format
msgid " --disable-auto-image-base Do not auto-choose image base. (default)\n"
-msgstr " --disable-auto-image-base No escoger automáticamente una imagen base. (por defecto)\n"
+msgstr " --disable-auto-image-base No escoge automáticamente una imagen base. (por defecto)\n"
-#: emultempl/pe.em:336
+#: emultempl/pe.em:343
#, c-format
msgid ""
" --dll-search-prefix=<string> When linking dynamically to a dll without\n"
@@ -201,44 +201,44 @@ msgid ""
" in preference to lib<basename>.dll \n"
msgstr ""
" --dll-search-prefix=<cadena> Al enlazar dinámicamente con una dll sin una\n"
-" biblioteca de importación, usar <cadena><nombrebase>.dll \n"
+" biblioteca de importación, usa <cadena><nombrebase>.dll \n"
" en lugar de lib<nombrebase>.dll \n"
-#: emultempl/pe.em:339
+#: emultempl/pe.em:346
#, c-format
msgid ""
" --enable-auto-import Do sophistcated linking of _sym to\n"
" __imp_sym for DATA references\n"
msgstr ""
-" --enable-auto-import Hacer enlazado sofisticado de _sym a\n"
+" --enable-auto-import Hace enlazado sofisticado de _sym a\n"
" __imp_sym para las referencias DATA\n"
-#: emultempl/pe.em:341
+#: emultempl/pe.em:348
#, c-format
msgid " --disable-auto-import Do not auto-import DATA items from DLLs\n"
-msgstr " --disable-auto-import No importar automáticamente elementos DATA de las DLLs\n"
+msgstr " --disable-auto-import No importa automáticamente elementos DATA de las DLLs\n"
-#: emultempl/pe.em:342
+#: emultempl/pe.em:349
#, c-format
msgid ""
" --enable-runtime-pseudo-reloc Work around auto-import limitations by\n"
" adding pseudo-relocations resolved at\n"
" runtime.\n"
msgstr ""
-" --enable-runtime-pseudo-reloc Evitar limitaciones de autoimportación\n"
+" --enable-runtime-pseudo-reloc Evita limitaciones de autoimportación\n"
" agregando pseudo-reubicaciones resueltas\n"
" al momento de ejecución.\n"
-#: emultempl/pe.em:345
+#: emultempl/pe.em:352
#, c-format
msgid ""
" --disable-runtime-pseudo-reloc Do not add runtime pseudo-relocations for\n"
" auto-imported DATA.\n"
msgstr ""
-" --disable-runtime-pseudo-reloc No agregar pseudo-reubicaciones al momento\n"
+" --disable-runtime-pseudo-reloc No agrega pseudo-reubicaciones al momento\n"
" de ejecución para DATOS autoimportados.\n"
-#: emultempl/pe.em:347
+#: emultempl/pe.em:354
#, c-format
msgid ""
" --enable-extra-pe-debug Enable verbose debug output when building\n"
@@ -247,91 +247,95 @@ msgstr ""
" --enable-extra-pe-debug Activa la salida de depuración detallada al construir\n"
" o enlazar a DLLs (en part. con auto-importación)\n"
-#: emultempl/pe.em:350
+#: emultempl/pe.em:357
#, c-format
msgid ""
" --large-address-aware Executable supports virtual addresses\n"
" greater than 2 gigabytes\n"
msgstr ""
-" --large-address-aware El ejecutable tiene soporte para direcciones\n"
+" --large-address-aware El ejecutable admite direcciones\n"
" virtuales mayores a 2 gigabytes\n"
-#: emultempl/pe.em:417
+#: emultempl/pe.em:424
msgid "%P: warning: bad version number in -subsystem option\n"
msgstr "%P: aviso: número de versión erróneo en la opción -subsystem\n"
-#: emultempl/pe.em:448
+#: emultempl/pe.em:455
msgid "%P%F: invalid subsystem type %s\n"
msgstr "%P%F: tipo de subsistema %s inválido\n"
-#: emultempl/pe.em:487
+#: emultempl/pe.em:494
msgid "%P%F: invalid hex number for PE parameter '%s'\n"
msgstr "%P%F: número hexadecimal inválido para el parámetro PE '%s'\n"
-#: emultempl/pe.em:504
+#: emultempl/pe.em:511
msgid "%P%F: strange hex info for PE parameter '%s'\n"
msgstr "%P%F: información hexadecimal extraña para el parámetro PE '%s'\n"
-#: emultempl/pe.em:521
+#: emultempl/pe.em:528
#, c-format
msgid "%s: Can't open base file %s\n"
msgstr "%s: No se puede abrir el fichero base %s\n"
-#: emultempl/pe.em:737
+#: emultempl/pe.em:744
msgid "%P: warning, file alignment > section alignment.\n"
msgstr "%P: aviso, alineación del fichero > alineación de la sección.\n"
-#: emultempl/pe.em:824 emultempl/pe.em:851
+#: emultempl/pe.em:831 emultempl/pe.em:858
#, c-format
msgid "Warning: resolving %s by linking to %s\n"
-msgstr "Aviso: resolviendo %s al enlazar con %s\n"
+msgstr "Aviso: se resuelve %s al enlazar con %s\n"
-#: emultempl/pe.em:829 emultempl/pe.em:856
+#: emultempl/pe.em:836 emultempl/pe.em:863
msgid "Use --enable-stdcall-fixup to disable these warnings\n"
msgstr "Use --enable-stdcall-fixup para desactivar estos avisos\n"
-#: emultempl/pe.em:830 emultempl/pe.em:857
+#: emultempl/pe.em:837 emultempl/pe.em:864
msgid "Use --disable-stdcall-fixup to disable these fixups\n"
msgstr "Use --disable-stdcall-fixup para desactivar estas composturas\n"
-#: emultempl/pe.em:876
+#: emultempl/pe.em:883
#, c-format
msgid "%C: Cannot get section contents - auto-import exception\n"
msgstr "%C: No se puede obtener el contenido de la sección - excepción de auto-importación\n"
-#: emultempl/pe.em:913
+#: emultempl/pe.em:920
#, c-format
msgid "Info: resolving %s by linking to %s (auto-import)\n"
-msgstr "Información: resolviendo %s al enlazar con %s (auto-importación)\n"
+msgstr "Información: se resuelve %s al enlazar con %s (auto-importación)\n"
-#: emultempl/pe.em:986
-msgid "%F%P: PE operations on non PE file.\n"
-msgstr "%F%P: operaciones PE en un fichero que no es PE.\n"
+#: emultempl/pe.em:992
+msgid "%F%P: cannot perform PE operations on non PE output file '%B'.\n"
+msgstr "%F%P: no se pueden realizar operaciones PE en el fichero de salida '%B' que no es PE.\n"
-#: emultempl/pe.em:1261
+#: emultempl/pe.em:1334
#, c-format
msgid "Errors encountered processing file %s\n"
msgstr "Se encontraron errores al procesar el fichero %s\n"
-#: emultempl/pe.em:1284
+#: emultempl/pe.em:1357
#, c-format
msgid "Errors encountered processing file %s for interworking"
msgstr "Se encontraron errores el procesar el fichero %s para interoperabilidad"
-#: emultempl/pe.em:1345 ldexp.c:522 ldlang.c:2946 ldlang.c:5800 ldlang.c:5831
+#: emultempl/pe.em:1418 ldexp.c:530 ldlang.c:3082 ldlang.c:6087 ldlang.c:6118
#: ldmain.c:1167
msgid "%P%F: bfd_link_hash_lookup failed: %E\n"
msgstr "%P%F: falló bfd_link_hash_lookup: %E\n"
-#: ldcref.c:154
+#: ldcref.c:166
msgid "%X%P: bfd_hash_table_init of cref table failed: %E\n"
msgstr "%X%P: falló bfd_hash_table_init de la tabla cref: %E\n"
-#: ldcref.c:160
+#: ldcref.c:172
msgid "%X%P: cref_hash_lookup failed: %E\n"
msgstr "%X%P: falló cref_hash_lookup: %E\n"
-#: ldcref.c:226
+#: ldcref.c:182
+msgid "%X%P: cref alloc failed: %E\n"
+msgstr "%X%P: falló la reubicación cref: %E\n"
+
+#: ldcref.c:362
#, c-format
msgid ""
"\n"
@@ -342,33 +346,33 @@ msgstr ""
"Tabla de Referencias Cruzadas\n"
"\n"
-#: ldcref.c:227
+#: ldcref.c:363
msgid "Symbol"
msgstr "Símbolo"
-#: ldcref.c:235
+#: ldcref.c:371
#, c-format
msgid "File\n"
msgstr "Fichero\n"
-#: ldcref.c:239
+#: ldcref.c:375
#, c-format
msgid "No symbols\n"
msgstr "No hay símbolos\n"
-#: ldcref.c:360 ldcref.c:482
+#: ldcref.c:496 ldcref.c:618
msgid "%B%F: could not read symbols; %E\n"
msgstr "%B%F: no se pueden leer símbolos; %E\n"
-#: ldcref.c:364 ldcref.c:486 ldmain.c:1232 ldmain.c:1236
+#: ldcref.c:500 ldcref.c:622 ldmain.c:1232 ldmain.c:1236
msgid "%B%F: could not read symbols: %E\n"
msgstr "%B%F: no se pueden leer símbolos: %E\n"
-#: ldcref.c:415
+#: ldcref.c:551
msgid "%P: symbol `%T' missing from main hash table\n"
msgstr "%P: falta el símbolo `%T' de la tabla principal de dispersión\n"
-#: ldcref.c:557 ldcref.c:564 ldmain.c:1279 ldmain.c:1286
+#: ldcref.c:693 ldcref.c:700 ldmain.c:1279 ldmain.c:1286
msgid "%B%F: could not read relocs: %E\n"
msgstr "%B%F: no se pueden leer las reubicaciones: %E\n"
@@ -376,7 +380,7 @@ msgstr "%B%F: no se pueden leer las reubicaciones: %E\n"
#. in OUTSECNAME. This reloc is from a section which is
#. mapped into a section from which references to OUTSECNAME
#. are prohibited. We must report an error.
-#: ldcref.c:591
+#: ldcref.c:727
msgid "%X%C: prohibited cross reference from %s to `%T' in %s\n"
msgstr "%X%C: referencia cruzada prohibida de %s a `%T' en %s\n"
@@ -390,11 +394,11 @@ msgstr "%P%X: Formatos diferentes de fichero objeto componen al conjunto %s\n"
#: ldctor.c:281 ldctor.c:295
msgid "%P%X: %s does not support reloc %s for set %s\n"
-msgstr "%P%X: %s no tiene soporte para la reubicación para el conjunto %s\n"
+msgstr "%P%X: %s no admite la reubicación %s para el conjunto %s\n"
#: ldctor.c:316
msgid "%P%X: Unsupported size %d for set %s\n"
-msgstr "%P%X: Tamaño %d sin soporte para el conjunto %s\n"
+msgstr "%P%X: No se admite el tamaño %d para el conjunto %s\n"
#: ldctor.c:337
msgid ""
@@ -406,86 +410,96 @@ msgstr ""
"Conjunto Símbolo\n"
"\n"
-#: ldemul.c:236
+#: ldemul.c:235
#, c-format
msgid "%S SYSLIB ignored\n"
msgstr "%S se ignora SYSLIB\n"
-#: ldemul.c:242
+#: ldemul.c:241
#, c-format
msgid "%S HLL ignored\n"
msgstr "%S se ignora HLL\n"
-#: ldemul.c:262
+#: ldemul.c:261
msgid "%P: unrecognised emulation mode: %s\n"
msgstr "%P: no se reconoce el modo de emulación: %s\n"
-#: ldemul.c:263
+#: ldemul.c:262
msgid "Supported emulations: "
-msgstr "Emulaciones con soporte: "
+msgstr "Emulaciones admitidas: "
-#: ldemul.c:305
+#: ldemul.c:304
#, c-format
msgid " no emulation specific options.\n"
msgstr " no hay opciones específicas de emulación.\n"
-#: ldexp.c:338
+#: ldexp.c:344
#, c-format
msgid "%F%S %% by zero\n"
msgstr "%F%S %% por cero\n"
-#: ldexp.c:346
+#: ldexp.c:352
#, c-format
msgid "%F%S / by zero\n"
msgstr "%F%S / por cero\n"
-#: ldexp.c:536
+#: ldexp.c:544
#, c-format
msgid "%X%S: unresolvable symbol `%s' referenced in expression\n"
msgstr "%X%S: símbolo `%s' sin resolución referenciado en la expresión\n"
-#: ldexp.c:547
+#: ldexp.c:555
#, c-format
msgid "%F%S: undefined symbol `%s' referenced in expression\n"
msgstr "%F%S: símbolo `%s' indefinido referenciado en la expresión\n"
-#: ldexp.c:608 ldexp.c:621
+#: ldexp.c:576 ldexp.c:593 ldexp.c:619
+#, c-format
+msgid "%F%S: undefined section `%s' referenced in expression\n"
+msgstr "%F%S: sección `%s' indefinida referenciada en la expresión\n"
+
+#: ldexp.c:645 ldexp.c:658
#, c-format
msgid "%F%S: undefined MEMORY region `%s' referenced in expression\n"
msgstr "%F%S: región MEMORY `%s' indefinida referenciada en la expresión\n"
-#: ldexp.c:683
+#: ldexp.c:669
+#, c-format
+msgid "%F%S: unknown constant `%s' referenced in expression\n"
+msgstr "%F%S: constante `%s' indefinida referenciada en la expresión\n"
+
+#: ldexp.c:730
#, c-format
msgid "%F%S can not PROVIDE assignment to location counter\n"
msgstr "%F%S no puede hacer una asignación PROVIDE al contador de ubicación\n"
-#: ldexp.c:697
+#: ldexp.c:744
#, c-format
msgid "%F%S invalid assignment to location counter\n"
msgstr "%F%S asignación inválida al contador de ubicación\n"
-#: ldexp.c:700
+#: ldexp.c:747
#, c-format
msgid "%F%S assignment to location counter invalid outside of SECTION\n"
msgstr "%F%S asignación al contador de ubicación es inválida fuera de SECTION\n"
-#: ldexp.c:709
+#: ldexp.c:756
msgid "%F%S cannot move location counter backwards (from %V to %V)\n"
msgstr "%F%S no se puede mover el contador de ubicación hacia atrás (de %V a %V)\n"
-#: ldexp.c:748
+#: ldexp.c:795
msgid "%P%F:%s: hash creation failed\n"
msgstr "%P%F:%s: falló la creación de la dispersión\n"
-#: ldexp.c:1000 ldexp.c:1025
+#: ldexp.c:1054 ldexp.c:1079
#, c-format
msgid "%F%S nonconstant expression for %s\n"
msgstr "%F%S expresión no constante para %s\n"
-#: ldexp.c:1082
+#: ldexp.c:1138
#, c-format
-msgid "%F%S non constant expression for %s\n"
-msgstr "%F%S expresión no constante para %s\n"
+msgid "%F%S: nonconstant expression for %s\n"
+msgstr "%F%S: expresión no constante para %s\n"
#: ldfile.c:139
#, c-format
@@ -501,65 +515,76 @@ msgstr "tuvo éxito el intento de abrir %s\n"
msgid "%F%P: invalid BFD target `%s'\n"
msgstr "%F%P: objetivo BFD inválido `%s'\n"
-#: ldfile.c:255 ldfile.c:282
+#: ldfile.c:256 ldfile.c:285
msgid "%P: skipping incompatible %s when searching for %s\n"
msgstr "%P: saltando el %s incompatible mientras se buscaba %s\n"
-#: ldfile.c:267
+#: ldfile.c:269
msgid "%F%P: attempted static link of dynamic object `%s'\n"
msgstr "%F%P: se intentó el enlazado estático del objeto dinámico `%s'\n"
-#: ldfile.c:384
+#: ldfile.c:388
msgid "%F%P: %s (%s): No such file: %E\n"
msgstr "%F%P: %s (%s): No hay tal fichero: %E\n"
-#: ldfile.c:387
+#: ldfile.c:391
msgid "%F%P: %s: No such file: %E\n"
msgstr "%F%P: %s No hay tal fichero: %E\n"
-#: ldfile.c:417
+#: ldfile.c:421
msgid "%F%P: cannot find %s inside %s\n"
msgstr "%F%P: no se puede encontrar %s dentro de %s\n"
-#: ldfile.c:420
+#: ldfile.c:424
msgid "%F%P: cannot find %s\n"
msgstr "%F%P: no se puede encontrar %s\n"
-#: ldfile.c:437 ldfile.c:453
+#: ldfile.c:441 ldfile.c:457
#, c-format
msgid "cannot find script file %s\n"
msgstr "no se puede encontrar el fichero de guión %s\n"
-#: ldfile.c:439 ldfile.c:455
+#: ldfile.c:443 ldfile.c:459
#, c-format
msgid "opened script file %s\n"
msgstr "fichero de guión %s abierto\n"
-#: ldfile.c:499
+#: ldfile.c:503
msgid "%P%F: cannot open linker script file %s: %E\n"
msgstr "%P%F: no se puede abrir el fichero de guión del enlazador %s: %E\n"
-#: ldfile.c:546
+#: ldfile.c:550
msgid "%P%F: cannot represent machine `%s'\n"
msgstr "%P%F: no se puede representar la máquina `%s'\n"
-#: ldlang.c:940 ldlang.c:982 ldlang.c:2695
+#: ldlang.c:1069 ldlang.c:1111 ldlang.c:2831
msgid "%P%F: can not create hash table: %E\n"
msgstr "%P%F: no se puede crear la tabla de dispersión: %E\n"
-#: ldlang.c:1025
+#: ldlang.c:1154
msgid "%P:%S: warning: redeclaration of memory region '%s'\n"
msgstr "%P:%S: aviso: redeclaración de la región de memoria '%s'\n"
-#: ldlang.c:1031
+#: ldlang.c:1160
msgid "%P:%S: warning: memory region %s not declared\n"
msgstr "%P:%S: aviso: no se declaró la región %s\n"
-#: ldlang.c:1108 ldlang.c:1135
+#: ldlang.c:1240 ldlang.c:1270
msgid "%P%F: failed creating section `%s': %E\n"
msgstr "%P%F: falló la creación de la sección `%s': %E\n"
-#: ldlang.c:1601
+#: ldlang.c:1754
+#, c-format
+msgid ""
+"\n"
+"Discarded input sections\n"
+"\n"
+msgstr ""
+"\n"
+"Secciones de salida descartadas\n"
+"\n"
+
+#: ldlang.c:1762
msgid ""
"\n"
"Memory Configuration\n"
@@ -569,23 +594,23 @@ msgstr ""
"Configuración de la Memoria\n"
"\n"
-#: ldlang.c:1603
+#: ldlang.c:1764
msgid "Name"
msgstr "Nombre"
-#: ldlang.c:1603
+#: ldlang.c:1764
msgid "Origin"
msgstr "Origen"
-#: ldlang.c:1603
+#: ldlang.c:1764
msgid "Length"
msgstr "Longitud"
-#: ldlang.c:1603
+#: ldlang.c:1764
msgid "Attributes"
msgstr "Atributos"
-#: ldlang.c:1643
+#: ldlang.c:1804
#, c-format
msgid ""
"\n"
@@ -596,154 +621,158 @@ msgstr ""
"Guión del enlazador y mapa de memoria\n"
"\n"
-#: ldlang.c:1709
+#: ldlang.c:1871
msgid "%P%F: Illegal use of `%s' section\n"
msgstr "%P%F: Uso ilegal de la sección `%s'\n"
-#: ldlang.c:1716
+#: ldlang.c:1879
msgid "%P%F: output format %s cannot represent section called %s\n"
msgstr "%P%F: el formato de salida %s no puede representar la sección llamada %s\n"
-#: ldlang.c:2313
+#: ldlang.c:2429
msgid "%B: file not recognized: %E\n"
-msgstr "%B: fichero no reconocido: %E\n"
+msgstr "%B: no se reconoce el fichero: %E\n"
-#: ldlang.c:2314
+#: ldlang.c:2430
msgid "%B: matching formats:"
msgstr "%B: formatos coincidentes:"
-#: ldlang.c:2321
+#: ldlang.c:2437
msgid "%F%B: file not recognized: %E\n"
-msgstr "%F%B: fichero no reconocido: %E\n"
+msgstr "%F%B: no se reconoce el fichero: %E\n"
-#: ldlang.c:2385
+#: ldlang.c:2507
msgid "%F%B: member %B in archive is not an object\n"
msgstr "%F%B: el miembro %B en el archivo no es un objeto\n"
-#: ldlang.c:2396 ldlang.c:2410
+#: ldlang.c:2518 ldlang.c:2532
msgid "%F%B: could not read symbols: %E\n"
msgstr "%F%B: no se puede leer símbolos: %E\n"
-#: ldlang.c:2665
+#: ldlang.c:2801
msgid "%P: warning: could not find any targets that match endianness requirement\n"
msgstr "%P: aviso: no se puede encontrar ningún objetivo que coincida con los requerimientos de endianess\n"
-#: ldlang.c:2679
+#: ldlang.c:2815
msgid "%P%F: target %s not found\n"
msgstr "%P%F: no se encuentra el objetivo %s\n"
-#: ldlang.c:2681
+#: ldlang.c:2817
msgid "%P%F: cannot open output file %s: %E\n"
msgstr "%P%F: no se puede abrir el fichero de salida %s: %E\n"
-#: ldlang.c:2687
+#: ldlang.c:2823
msgid "%P%F:%s: can not make object file: %E\n"
msgstr "%P%F:%s: no se puede hacer el fichero objeto: %E\n"
-#: ldlang.c:2691
+#: ldlang.c:2827
msgid "%P%F:%s: can not set architecture: %E\n"
msgstr "%P%F:%s: no se puede establecer la arquitectura: %E\n"
-#: ldlang.c:2839
+#: ldlang.c:2975
msgid "%P%F: bfd_hash_lookup failed creating symbol %s\n"
msgstr "%P%F: falló bfd_hash_lookup al crear el símbolo %s\n"
-#: ldlang.c:2857
+#: ldlang.c:2993
msgid "%P%F: bfd_hash_allocate failed creating symbol %s\n"
msgstr "%P%F: falló bfd_hash_allocate al crear el símbolo %s\n"
-#: ldlang.c:3288
+#: ldlang.c:3426
msgid " load address 0x%V"
msgstr " cargar la dirección 0x%V"
-#: ldlang.c:3528
+#: ldlang.c:3661
msgid "%W (size before relaxing)\n"
msgstr "%W (tamaño antes de la relajación)\n"
-#: ldlang.c:3615
+#: ldlang.c:3747
#, c-format
msgid "Address of section %s set to "
msgstr "La dirección de la sección %s se estableció a "
-#: ldlang.c:3768
+#: ldlang.c:3900
#, c-format
msgid "Fail with %d\n"
msgstr "Falló con %d\n"
-#: ldlang.c:4040
+#: ldlang.c:4172
msgid "%X%P: section %s [%V -> %V] overlaps section %s [%V -> %V]\n"
msgstr "%X%P: la sección %s [%V -> %V] sobreescribe a la sección %s [%V -> %V]\n"
-#: ldlang.c:4065
+#: ldlang.c:4197
msgid "%X%P: address 0x%v of %B section %s is not within region %s\n"
msgstr "%X%P: la dirección 0x%v de %B sección %s no está dentro de la región %s\n"
-#: ldlang.c:4074
+#: ldlang.c:4206
msgid "%X%P: region %s is full (%B section %s)\n"
msgstr "%X%P: la región %s está llena (%B sección %s)\n"
-#: ldlang.c:4114
+#: ldlang.c:4247
#, c-format
msgid "%F%S: non constant or forward reference address expression for section %s\n"
msgstr "%F%S: expresión de dirección de referencia hacia adelante o no constante para la sección %s\n"
-#: ldlang.c:4139
+#: ldlang.c:4272
msgid "%P%X: Internal error on COFF shared library section %s\n"
msgstr "%P%X: Error interno en la sección %s de biblioteca compartida COFF\n"
-#: ldlang.c:4197
+#: ldlang.c:4331
msgid "%P%F: error: no memory region specified for loadable section `%s'\n"
msgstr "%P%F: aviso: no se especificó una región de memoria para la sección cargable `%s'\n"
-#: ldlang.c:4202
+#: ldlang.c:4336
msgid "%P: warning: no memory region specified for loadable section `%s'\n"
msgstr "%P: aviso: no se especificó una región de memoria para la sección cargable `%s'\n"
-#: ldlang.c:4224
+#: ldlang.c:4358
msgid "%P: warning: changing start of section %s by %lu bytes\n"
msgstr "%P: aviso: cambiando el inicio de la sección %s por %lu bytes\n"
-#: ldlang.c:4388
+#: ldlang.c:4437
+msgid "%P: warning: dot moved backwards before `%s'\n"
+msgstr "%P: aviso: el punto se movió hacia atrás antes de `%s'\n"
+
+#: ldlang.c:4609
msgid "%P%F: can't relax section: %E\n"
msgstr "%P%F: no se puede relajar la sección: %E\n"
-#: ldlang.c:4636
+#: ldlang.c:4898
msgid "%F%P: invalid data statement\n"
msgstr "%F%P: declaración inválida de datos\n"
-#: ldlang.c:4669
+#: ldlang.c:4931
msgid "%F%P: invalid reloc statement\n"
msgstr "%F%P: declaración inválida de reubicación\n"
-#: ldlang.c:4802
+#: ldlang.c:5063
msgid "%P%F:%s: can't set start address\n"
msgstr "%P%F:%s: no se puede establecer la dirección de inicio\n"
-#: ldlang.c:4815 ldlang.c:4834
+#: ldlang.c:5076 ldlang.c:5095
msgid "%P%F: can't set start address\n"
msgstr "%P%F: no se puede establecer la dirección de inicio\n"
-#: ldlang.c:4827
+#: ldlang.c:5088
msgid "%P: warning: cannot find entry symbol %s; defaulting to %V\n"
-msgstr "%P: aviso: no se puede encontrar el símbolo de entrada %s; usando por defecto %V\n"
+msgstr "%P: aviso: no se puede encontrar el símbolo de entrada %s; se usa por defecto %V\n"
-#: ldlang.c:4839
+#: ldlang.c:5100
msgid "%P: warning: cannot find entry symbol %s; not setting start address\n"
msgstr "%P: aviso: no se puede encontrar el símbolo de entrada %s; no se establece la dirección de inicio\n"
-#: ldlang.c:4888
+#: ldlang.c:5149
msgid "%P%F: Relocatable linking with relocations from format %s (%B) to format %s (%B) is not supported\n"
msgstr "%P%F: No tiene soporte el enlazado reubicable con reubicaciones del formato %s (%B) al formato %s (%B)\n"
-#: ldlang.c:4898
-msgid "%P: warning: %s architecture of input file `%B' is incompatible with %s output\n"
-msgstr "%P: aviso: la arquitectura %s del fichero de entrada `%B' es incompatible con la salida %s\n"
+#: ldlang.c:5159
+msgid "%P%X: %s architecture of input file `%B' is incompatible with %s output\n"
+msgstr "%P%X: la arquitectura %s del fichero de entrada `%B' es incompatible con la salida %s\n"
-#: ldlang.c:4920
+#: ldlang.c:5181
msgid "%P%X: failed to merge target specific data of file %B\n"
msgstr "%P%X: falló la mezcla de datos específicos de objetivo del fichero %B\n"
-#: ldlang.c:5004
+#: ldlang.c:5265
msgid ""
"\n"
"Allocating common symbols\n"
@@ -751,7 +780,7 @@ msgstr ""
"\n"
"Asignando símbolos comunes\n"
-#: ldlang.c:5005
+#: ldlang.c:5266
msgid ""
"Common symbol size file\n"
"\n"
@@ -759,81 +788,81 @@ msgstr ""
"Símbolo común tamaño fichero\n"
"\n"
-#: ldlang.c:5131
+#: ldlang.c:5401
msgid "%P%F: invalid syntax in flags\n"
msgstr "%P%F: sintaxis inválida en los interruptores\n"
-#: ldlang.c:5406
+#: ldlang.c:5714
msgid "%P%F: Failed to create hash table\n"
msgstr "%P%F: Falló al crear la tabla de dispersión\n"
-#: ldlang.c:5722
+#: ldlang.c:6009
msgid "%P%F: multiple STARTUP files\n"
msgstr "%P%F: ficheros STARTUP múltiples\n"
-#: ldlang.c:5770
+#: ldlang.c:6057
msgid "%X%P:%S: section has both a load address and a load region\n"
msgstr "%X%P:%S: la sección tiene tanto una dirección de carga como una región de carga\n"
-#: ldlang.c:6007
+#: ldlang.c:6314
msgid "%F%P: bfd_record_phdr failed: %E\n"
msgstr "%F%P: falló bfd_record_phdr: %E\n"
-#: ldlang.c:6027
+#: ldlang.c:6334
msgid "%X%P: section `%s' assigned to non-existent phdr `%s'\n"
-msgstr "%X%P: se asignó la sección `%s' al phdr no existente `%s'\n"
+msgstr "%X%P: se asignó la sección `%s' al phdr que no existe `%s'\n"
-#: ldlang.c:6418
+#: ldlang.c:6725
msgid "%X%P: unknown language `%s' in version information\n"
msgstr "%X%P: lenguaje `%s' desconocido en la información de la versión\n"
-#: ldlang.c:6560
+#: ldlang.c:6867
msgid "%X%P: anonymous version tag cannot be combined with other version tags\n"
msgstr "%X%P: la marca de versión anónima no se puede combinar con otras marcas de versión\n"
-#: ldlang.c:6569
+#: ldlang.c:6876
msgid "%X%P: duplicate version tag `%s'\n"
msgstr "%X%P: marca de versión `%s' duplicada\n"
-#: ldlang.c:6589 ldlang.c:6598 ldlang.c:6615 ldlang.c:6625
+#: ldlang.c:6896 ldlang.c:6905 ldlang.c:6922 ldlang.c:6932
msgid "%X%P: duplicate expression `%s' in version information\n"
msgstr "%X%P: expresión `%s' duplicada en la información de la versión\n"
-#: ldlang.c:6665
+#: ldlang.c:6972
msgid "%X%P: unable to find version dependency `%s'\n"
msgstr "%X%P: no se puede encontrar la dependencia de versión `%s'\n"
-#: ldlang.c:6687
+#: ldlang.c:6994
msgid "%X%P: unable to read .exports section contents\n"
msgstr "%X%P: no se pueden leer los contenidos de la sección .exports\n"
-#: ldmain.c:232
+#: ldmain.c:234
msgid "%X%P: can't set BFD default target to `%s': %E\n"
msgstr "%X%P: no se puede establecer el objetivo BFD por defecto a `%s': %E\n"
-#: ldmain.c:345
+#: ldmain.c:298
msgid "%P%F: --relax and -r may not be used together\n"
msgstr "%P%F: no se pueden usar juntos -relax y -r\n"
-#: ldmain.c:347
+#: ldmain.c:300
msgid "%P%F: -r and -shared may not be used together\n"
msgstr "%P%F: no se pueden usar juntos -r y -shared\n"
-#: ldmain.c:353
+#: ldmain.c:343
msgid "%P%F: -F may not be used without -shared\n"
msgstr "%P%F: no se puede usar -F sin -shared\n"
-#: ldmain.c:355
+#: ldmain.c:345
msgid "%P%F: -f may not be used without -shared\n"
msgstr "%P%F: no se puede usar -f sin -shared\n"
#: ldmain.c:397
msgid "using external linker script:"
-msgstr "usando el guión externo del enlazador:"
+msgstr "se usa el guión externo del enlazador:"
#: ldmain.c:399
msgid "using internal linker script:"
-msgstr "usando el guión interno del enlazador:"
+msgstr "se usa el guión interno del enlazador:"
#: ldmain.c:433
msgid "%P%F: no input files\n"
@@ -849,7 +878,7 @@ msgstr "%P%F: no se puede encontrar el fichero de mapeo %s: %E\n"
#: ldmain.c:485
msgid "%P: link errors found, deleting executable `%s'\n"
-msgstr "%P: se encontraron errores de enlace, borrando el ejecutable `%s'\n"
+msgstr "%P: se encontraron errores de enlace, se borra el ejecutable `%s'\n"
#: ldmain.c:494
msgid "%F%B: final close failed: %E\n"
@@ -867,7 +896,7 @@ msgstr "%X%P: no se puede abrir para el destino de la copia `%s'\n"
msgid "%P: Error writing file `%s'\n"
msgstr "%P: Error al escribir el fichero `%s'\n"
-#: ldmain.c:535 pe-dll.c:1494
+#: ldmain.c:535 pe-dll.c:1572
#, c-format
msgid "%P: Error closing file `%s'\n"
msgstr "%P: Error al cerrar el fichero `%s'\n"
@@ -875,7 +904,7 @@ msgstr "%P: Error al cerrar el fichero `%s'\n"
#: ldmain.c:551
#, c-format
msgid "%s: total time in link: %ld.%06ld\n"
-msgstr "%s: tiempo total en el enlazado: %ld.%06ld\n"
+msgstr "%s: tiempo total de enlazado: %ld.%06ld\n"
#: ldmain.c:554
#, c-format
@@ -925,7 +954,7 @@ msgstr "%D: primero se definió aquí\n"
#: ldmain.c:1021
msgid "%P: Disabling relaxation: it will not work with multiple definitions\n"
-msgstr "%P: Desactivandola la relajación: no trabajará con definiciones múltiples\n"
+msgstr "%P: Se desactiva la relajación: no funcionará con definiciones múltiples\n"
# FIXME: Revisar en el código fuente si `common' se refiere a una orden o
# se puede sustituir por `común'. cfuga
@@ -939,7 +968,7 @@ msgstr "%B: aviso: common está aquí\n"
#: ldmain.c:1061
msgid "%B: warning: common of `%T' overridden by definition\n"
-msgstr "%B: aviso: el common de `%T' es sobrepasado por definición\n"
+msgstr "%B: aviso: el common de `%T' se sobrepasa por definición\n"
#: ldmain.c:1064
msgid "%B: warning: defined here\n"
@@ -1047,52 +1076,52 @@ msgstr "%X%C: reubicación peligrosa: %s\n"
msgid "%X%C: reloc refers to symbol `%T' which is not being output\n"
msgstr "%X%C: la reubicación se refiere al símbolo `%T' el cual no se muestra\n"
-#: ldmisc.c:147
+#: ldmisc.c:148
#, c-format
msgid "no symbol"
msgstr "no hay símbolo"
-#: ldmisc.c:238
+#: ldmisc.c:245
#, c-format
msgid "built in linker script:%u"
msgstr "guión interno del enlazador:%u"
-#: ldmisc.c:294 ldmisc.c:298
+#: ldmisc.c:301 ldmisc.c:305
msgid "%B%F: could not read symbols\n"
msgstr "%B%F: no se pueden leer los símbolos\n"
-#: ldmisc.c:340
-msgid "%B: In function `%T'"
-msgstr "%B: En la función `%T'"
+#: ldmisc.c:347
+msgid "%B: In function `%T':\n"
+msgstr "%B: En la función `%T':\n"
-#: ldmisc.c:510
+#: ldmisc.c:472
msgid "%F%P: internal error %s %d\n"
msgstr "%F%P: error interno %s %d\n"
-#: ldmisc.c:556
+#: ldmisc.c:521
msgid "%P: internal error: aborting at %s line %d in %s\n"
-msgstr "%P: error interno: abortando en %s línea %d en %s\n"
+msgstr "%P: error interno: se aborta en %s línea %d en %s\n"
-#: ldmisc.c:559
+#: ldmisc.c:524
msgid "%P: internal error: aborting at %s line %d\n"
-msgstr "%P: error interno: abortando en %s línea %d\n"
+msgstr "%P: error interno: se aborta en %s línea %d\n"
-#: ldmisc.c:561
+#: ldmisc.c:526
msgid "%P%F: please report this bug\n"
msgstr "%P%F: por favor reporte este bicho\n"
#. Output for noisy == 2 is intended to follow the GNU standards.
-#: ldver.c:38
+#: ldver.c:37
#, c-format
-msgid "GNU ld version %s\n"
-msgstr "GNU ld versión %s\n"
+msgid "GNU ld %s\n"
+msgstr "GNU ld %s\n"
-#: ldver.c:42
+#: ldver.c:41
#, c-format
-msgid "Copyright 2005 Free Software Foundation, Inc.\n"
-msgstr "Copyright 2005 Free Software Foundation, Inc.\n"
+msgid "Copyright 2007 Free Software Foundation, Inc.\n"
+msgstr "Copyright 2007 Free Software Foundation, Inc.\n"
-#: ldver.c:43
+#: ldver.c:42
#, c-format
msgid ""
"This program is free software; you may redistribute it under the terms of\n"
@@ -1102,10 +1131,10 @@ msgstr ""
"la Licencia Pública General de GNU. Este programa no tiene absolutamente\n"
"ninguna garantía.\n"
-#: ldver.c:52
+#: ldver.c:51
#, c-format
msgid " Supported emulations:\n"
-msgstr " Emulaciones con soporte:\n"
+msgstr " Emulaciones admitidas:\n"
#: ldwrite.c:55 ldwrite.c:191
msgid "%P%F: bfd_new_link_order failed\n"
@@ -1128,261 +1157,265 @@ msgstr "%8x algo más\n"
msgid "%F%P: final link failed: %E\n"
msgstr "%F%P: falló el enlace final: %E\n"
-#: lexsup.c:196 lexsup.c:328
+#: lexsup.c:205 lexsup.c:341
msgid "KEYWORD"
msgstr "PALABRA CLAVE"
-#: lexsup.c:196
+#: lexsup.c:205
msgid "Shared library control for HP/UX compatibility"
msgstr "Control de biblioteca compartida para compatibilidad con HP/UX"
-#: lexsup.c:199
+#: lexsup.c:208
msgid "ARCH"
msgstr "ARQ"
-#: lexsup.c:199
+#: lexsup.c:208
msgid "Set architecture"
-msgstr "Establecer la arquitectura"
+msgstr "Establece la arquitectura"
-#: lexsup.c:201 lexsup.c:422
+#: lexsup.c:210 lexsup.c:447
msgid "TARGET"
msgstr "OBJETIVO"
-#: lexsup.c:201
+#: lexsup.c:210
msgid "Specify target for following input files"
-msgstr "Especificar el objetivo para los siguientes ficheros de entrada"
+msgstr "Especifica el objetivo para los siguientes ficheros de entrada"
-#: lexsup.c:204 lexsup.c:253 lexsup.c:265 lexsup.c:278 lexsup.c:381
-#: lexsup.c:434 lexsup.c:491
+#: lexsup.c:213 lexsup.c:262 lexsup.c:274 lexsup.c:287 lexsup.c:289
+#: lexsup.c:402 lexsup.c:459 lexsup.c:516 lexsup.c:528
msgid "FILE"
msgstr "FICHERO"
-#: lexsup.c:204
+#: lexsup.c:213
msgid "Read MRI format linker script"
-msgstr "Leer el guión del enlazador de formato MRI"
+msgstr "Lee el guión del enlazador de formato MRI"
-#: lexsup.c:206
+#: lexsup.c:215
msgid "Force common symbols to be defined"
-msgstr "Forzar que los símbolos comunes sean definidos"
+msgstr "Fuerza que los símbolos comunes sean definidos"
-#: lexsup.c:210 lexsup.c:476 lexsup.c:478 lexsup.c:480
+#: lexsup.c:219 lexsup.c:501 lexsup.c:503 lexsup.c:505
msgid "ADDRESS"
msgstr "DIRECCIÓN"
-#: lexsup.c:210
+#: lexsup.c:219
msgid "Set start address"
-msgstr "Establecer la dirección de inicio"
+msgstr "Establece la dirección de inicio"
-#: lexsup.c:212
+#: lexsup.c:221
msgid "Export all dynamic symbols"
-msgstr "Exportar todos los símbolos dinámicos"
+msgstr "Exporta todos los símbolos dinámicos"
-#: lexsup.c:214
+#: lexsup.c:223
msgid "Link big-endian objects"
-msgstr "Enlazar objetos big-endian"
+msgstr "Enlaza objetos big-endian"
-#: lexsup.c:216
+#: lexsup.c:225
msgid "Link little-endian objects"
-msgstr "Enlazar objetos little-endian"
+msgstr "Enlaza objetos little-endian"
-#: lexsup.c:218 lexsup.c:221
+#: lexsup.c:227 lexsup.c:230
msgid "SHLIB"
msgstr "BIBCOMP"
-#: lexsup.c:218
+#: lexsup.c:227
msgid "Auxiliary filter for shared object symbol table"
msgstr "Filtro auxiliar para la tabla de símbolos de objetos compartidos"
-#: lexsup.c:221
+#: lexsup.c:230
msgid "Filter for shared object symbol table"
msgstr "Filtro para la tabla de símbolos de objetos compartidos"
-#: lexsup.c:224
+#: lexsup.c:233
msgid "Ignored"
-msgstr "Ignorado"
+msgstr "Se descarta"
-#: lexsup.c:226
+#: lexsup.c:235
msgid "SIZE"
msgstr "TAMAÑO"
-#: lexsup.c:226
+#: lexsup.c:235
msgid "Small data size (if no size, same as --shared)"
msgstr "Tamaño de los datos small (si no se especifica, es el mismo que --shared)"
-#: lexsup.c:229
+#: lexsup.c:238
msgid "FILENAME"
msgstr "FICHERO"
-#: lexsup.c:229
+#: lexsup.c:238
msgid "Set internal name of shared library"
-msgstr "Establecer el nombre interno de la biblioteca compartida"
+msgstr "Establece el nombre interno de la biblioteca compartida"
-#: lexsup.c:231
+#: lexsup.c:240
msgid "PROGRAM"
msgstr "PROGRAMA"
-#: lexsup.c:231
+#: lexsup.c:240
msgid "Set PROGRAM as the dynamic linker to use"
msgstr "Establece el PROGRAMA como el enlazador dinámico a utilizar"
-#: lexsup.c:234
+#: lexsup.c:243
msgid "LIBNAME"
msgstr "NOMBREBIB"
-#: lexsup.c:234
+#: lexsup.c:243
msgid "Search for library LIBNAME"
-msgstr "Buscar la biblioteca NOMBREBIB"
+msgstr "Busca la biblioteca NOMBREBIB"
-#: lexsup.c:236
+#: lexsup.c:245
msgid "DIRECTORY"
msgstr "DIRECTORIO"
-#: lexsup.c:236
+#: lexsup.c:245
msgid "Add DIRECTORY to library search path"
-msgstr "Agregar el DIRECTORIO a la ruta de búsqueda de bibliotecas"
+msgstr "Agrega el DIRECTORIO a la ruta de búsqueda de bibliotecas"
-#: lexsup.c:239
+#: lexsup.c:248
msgid "Override the default sysroot location"
-msgstr "Sobreescribir la ubicación de sysroot por defecto"
+msgstr "Sobreescribe la ubicación de sysroot por defecto"
-#: lexsup.c:241
+#: lexsup.c:250
msgid "EMULATION"
msgstr "EMULACIÓN"
-#: lexsup.c:241
+#: lexsup.c:250
msgid "Set emulation"
-msgstr "Establecer la emulación"
+msgstr "Establece la emulación"
-#: lexsup.c:243
+#: lexsup.c:252
msgid "Print map file on standard output"
-msgstr "Imprimir el fichero mapa en la salida estándar"
+msgstr "Imprime el fichero mapa en la salida estándar"
-#: lexsup.c:245
+#: lexsup.c:254
msgid "Do not page align data"
-msgstr "No paginar los datos alineados"
+msgstr "No pagina los datos alineados"
-#: lexsup.c:247
+#: lexsup.c:256
msgid "Do not page align data, do not make text readonly"
-msgstr "No paginar los datos alineados, no hacer el texto de sólo lectura"
+msgstr "No pagina los datos alineados, no hace el texto de sólo lectura"
-#: lexsup.c:250
+#: lexsup.c:259
msgid "Page align data, make text readonly"
-msgstr "Paginar los datos alineados, hacer el texto de sólo lectura"
+msgstr "Pagina los datos alineados, hace el texto de sólo lectura"
-#: lexsup.c:253
+#: lexsup.c:262
msgid "Set output file name"
-msgstr "Establecer el nombre del fichero de salida"
+msgstr "Establece el nombre del fichero de salida"
-#: lexsup.c:255
+#: lexsup.c:264
msgid "Optimize output file"
-msgstr "Optimizar la salida del fichero"
+msgstr "Optimiza la salida del fichero"
-#: lexsup.c:257
+#: lexsup.c:266
msgid "Ignored for SVR4 compatibility"
-msgstr "Ignorado por compatibilidad con SVR4"
+msgstr "Se descarta por compatibilidad con SVR4"
-#: lexsup.c:261
+#: lexsup.c:270
msgid "Generate relocatable output"
-msgstr "Generar salida reubicable"
+msgstr "Genera salida reubicable"
-#: lexsup.c:265
+#: lexsup.c:274
msgid "Just link symbols (if directory, same as --rpath)"
-msgstr "Sólo enlazar símbolos (si es un directorio, es igual que --rpath)"
+msgstr "Sólo enlaza símbolos (si es un directorio, es igual que --rpath)"
-#: lexsup.c:268
+#: lexsup.c:277
msgid "Strip all symbols"
-msgstr "Descartar todos los símbolos"
+msgstr "Descarta todos los símbolos"
-#: lexsup.c:270
+#: lexsup.c:279
msgid "Strip debugging symbols"
-msgstr "Descartar los símbolos de depuración"
+msgstr "Descarta los símbolos de depuración"
-#: lexsup.c:272
+#: lexsup.c:281
msgid "Strip symbols in discarded sections"
-msgstr "Descartar símbolos en las secciones descartadas"
+msgstr "Descarta símbolos en las secciones descartadas"
-#: lexsup.c:274
+#: lexsup.c:283
msgid "Do not strip symbols in discarded sections"
-msgstr "No descartar símbolos en las secciones descartadas"
+msgstr "No descarta símbolos en las secciones descartadas"
-#: lexsup.c:276
+#: lexsup.c:285
msgid "Trace file opens"
-msgstr "Rastrear la apertura de ficheros"
+msgstr "Rastrea la apertura de ficheros"
-#: lexsup.c:278
+#: lexsup.c:287
msgid "Read linker script"
-msgstr "Leer el guión del enlazador"
+msgstr "Lee el guión del enlazador"
+
+#: lexsup.c:289
+msgid "Read default linker script"
+msgstr "Lee el guión del enlazador por defecto"
-#: lexsup.c:280 lexsup.c:298 lexsup.c:364 lexsup.c:379 lexsup.c:469
-#: lexsup.c:494 lexsup.c:521
+#: lexsup.c:293 lexsup.c:311 lexsup.c:379 lexsup.c:400 lexsup.c:494
+#: lexsup.c:519 lexsup.c:554
msgid "SYMBOL"
msgstr "SÍMBOLO"
-#: lexsup.c:280
+#: lexsup.c:293
msgid "Start with undefined reference to SYMBOL"
-msgstr "Iniciar con una referencia sin definir hacia el SÍMBOLO"
+msgstr "Inicia con una referencia sin definir hacia el SÍMBOLO"
-#: lexsup.c:283
+#: lexsup.c:296
msgid "[=SECTION]"
msgstr "[=SECCIóN]"
-#: lexsup.c:284
+#: lexsup.c:297
msgid "Don't merge input [SECTION | orphan] sections"
-msgstr "No mezclar secciones de entrada [SECCIÓN | huérfanas]"
+msgstr "No mezcla secciones de entrada [SECCIÓN | huérfanas]"
-#: lexsup.c:286
+#: lexsup.c:299
msgid "Build global constructor/destructor tables"
-msgstr "Construir tablas globales de constructores/destructores"
+msgstr "Construye tablas globales de constructores/destructores"
-#: lexsup.c:288
+#: lexsup.c:301
msgid "Print version information"
-msgstr "Mostrar la información de la versión"
+msgstr "Muestra la información de la versión"
-#: lexsup.c:290
+#: lexsup.c:303
msgid "Print version and emulation information"
-msgstr "Mostrar la información de la versión y la emulación"
+msgstr "Muestra la información de la versión y la emulación"
-#: lexsup.c:292
+#: lexsup.c:305
msgid "Discard all local symbols"
-msgstr "Descartar todos los símbolos locales"
+msgstr "Descarta todos los símbolos locales"
-#: lexsup.c:294
+#: lexsup.c:307
msgid "Discard temporary local symbols (default)"
-msgstr "Descartar los símbolos locales temporales (por defecto)"
+msgstr "Descarta los símbolos locales temporales (por defecto)"
-#: lexsup.c:296
+#: lexsup.c:309
msgid "Don't discard any local symbols"
-msgstr "No descartar ningún símbolo local"
+msgstr "No descarta ningún símbolo local"
-#: lexsup.c:298
+#: lexsup.c:311
msgid "Trace mentions of SYMBOL"
-msgstr "Rastrear las menciones del SÍMBOLO"
+msgstr "Rastrea las menciones del SÍMBOLO"
-#: lexsup.c:300 lexsup.c:436 lexsup.c:438
+#: lexsup.c:313 lexsup.c:461 lexsup.c:463
msgid "PATH"
msgstr "RUTA"
-#: lexsup.c:300
+#: lexsup.c:313
msgid "Default search path for Solaris compatibility"
msgstr "Ruta de búsqueda por defecto para compatibilidad con Solaris"
-#: lexsup.c:303
+#: lexsup.c:316
msgid "Start a group"
-msgstr "Iniciar un grupo"
+msgstr "Inicia un grupo"
-#: lexsup.c:305
+#: lexsup.c:318
msgid "End a group"
-msgstr "Terminar un grupo"
+msgstr "Termina un grupo"
-#: lexsup.c:309
+#: lexsup.c:322
msgid "Accept input files whose architecture cannot be determined"
-msgstr "Aceptar ficheros de entrada cuya arquitectura no se pueda determinar"
+msgstr "Acepta ficheros de entrada cuya arquitectura no se pueda determinar"
-#: lexsup.c:313
+#: lexsup.c:326
msgid "Reject input files whose architecture is unknown"
-msgstr "Rechazar ficheros de entrada cuya arquitectura es desconocida"
+msgstr "Rechaza ficheros de entrada cuya arquitectura es desconocida"
-#: lexsup.c:316
+#: lexsup.c:329
msgid ""
"Set DT_NEEDED tags for DT_NEEDED entries in\n"
"\t\t\t\tfollowing dynamic libs"
@@ -1390,7 +1423,7 @@ msgstr ""
"Establece las marcas DT_NEEDED para las entradas DT_NEEDED en\n"
"\t\t\t\tlas bibliotecas dinámicas a continuación"
-#: lexsup.c:319
+#: lexsup.c:332
msgid ""
"Do not set DT_NEEDED tags for DT_NEEDED entries\n"
"\t\t\t\tin following dynamic libs"
@@ -1398,268 +1431,284 @@ msgstr ""
"No establece las marcas DT_NEEDED para las entradas DT_NEEDED en\n"
"\t\t\t\tlas bibliotecas dinámicas a continuación"
-#: lexsup.c:322
+#: lexsup.c:335
msgid "Only set DT_NEEDED for following dynamic libs if used"
msgstr "Sólo establece DT_NEEDED para las siguientes bibliotecas dinámicas si se usan"
-#: lexsup.c:325
+#: lexsup.c:338
msgid "Always set DT_NEEDED for following dynamic libs"
msgstr "Siempre establece DT_NEEDED para las siguientes bibliotecas dinámicas"
-#: lexsup.c:328
+#: lexsup.c:341
msgid "Ignored for SunOS compatibility"
-msgstr "Ignorado por compatibilidad con SunOS"
+msgstr "Se descarta por compatibilidad con SunOS"
-#: lexsup.c:330
+#: lexsup.c:343
msgid "Link against shared libraries"
-msgstr "Enlazar contra bibliotecas compartidas"
+msgstr "Enlaza contra bibliotecas compartidas"
-#: lexsup.c:336
+#: lexsup.c:349
msgid "Do not link against shared libraries"
-msgstr "No enlazar contra bibliotecas compartidas"
+msgstr "No enlaza contra bibliotecas compartidas"
-#: lexsup.c:344
+#: lexsup.c:357
msgid "Bind global references locally"
-msgstr "Asociar localmente las referencias globlales"
+msgstr "Asocia localmente las referencias globlales"
-#: lexsup.c:346
+#: lexsup.c:359
+msgid "Bind global function references locally"
+msgstr "Asocia localmente las referencias a función globales"
+
+#: lexsup.c:361
msgid "Check section addresses for overlaps (default)"
-msgstr "Revisar las direcciones de las secciones por traslapes (por defecto)"
+msgstr "Revisa las direcciones de las secciones por traslapes (por defecto)"
-#: lexsup.c:349
+#: lexsup.c:364
msgid "Do not check section addresses for overlaps"
-msgstr "No revisar las direcciones de las secciones por traslapes"
+msgstr "No revisa las direcciones de las secciones por traslapes"
-#: lexsup.c:352
+#: lexsup.c:367
msgid "Output cross reference table"
-msgstr "Mostrar la tabla de referencias cruzadas"
+msgstr "Muestra la tabla de referencias cruzadas"
-#: lexsup.c:354
+#: lexsup.c:369
msgid "SYMBOL=EXPRESSION"
msgstr "SÍMBOLO=EXPRESIÓN"
-#: lexsup.c:354
+#: lexsup.c:369
msgid "Define a symbol"
msgstr "Define un símbolo"
-#: lexsup.c:356
+#: lexsup.c:371
msgid "[=STYLE]"
msgstr "[=ESTILO]"
-#: lexsup.c:356
+#: lexsup.c:371
msgid "Demangle symbol names [using STYLE]"
msgstr "Desenreda los nombres de los símbolos [utilizando el ESTILO]"
# No me convence mucho la traducción de `embedded' por imbuído. cfuga
-#: lexsup.c:359
+#: lexsup.c:374
msgid "Generate embedded relocs"
msgstr "Genera reubicaciones imbuídas"
-#: lexsup.c:361
+#: lexsup.c:376
msgid "Treat warnings as errors"
-msgstr "Tratar los avisos como errores"
+msgstr "Trata los avisos como errores"
-#: lexsup.c:364
+#: lexsup.c:379
msgid "Call SYMBOL at unload-time"
-msgstr "Llamar al SÍMBOLO al momento de descargar"
+msgstr "Llama al SÍMBOLO al momento de descargar"
-#: lexsup.c:366
+#: lexsup.c:381
msgid "Force generation of file with .exe suffix"
-msgstr "Forzar la generación del fichero con sufijo .exe"
+msgstr "Fuerza la generación del fichero con sufijo .exe"
-#: lexsup.c:368
+#: lexsup.c:383
msgid "Remove unused sections (on some targets)"
-msgstr "Eliminar las secciones sin uso (en algunos objetivos)"
+msgstr "Elimina las secciones sin uso (en algunos objetivos)"
-#: lexsup.c:371
+#: lexsup.c:386
msgid "Don't remove unused sections (default)"
-msgstr "No eliminar las secciones sin uso (por defecto)"
+msgstr "No elimina las secciones sin uso (por defecto)"
-#: lexsup.c:374
+#: lexsup.c:389
+msgid "List removed unused sections on stderr"
+msgstr "Muestra las secciones sin uso eliminadas en la salida de error estándar"
+
+#: lexsup.c:392
+msgid "Do not list removed unused sections"
+msgstr "No muestra las secciones sin uso eliminadas"
+
+#: lexsup.c:395
msgid "Set default hash table size close to <NUMBER>"
msgstr "Establece el tamaño de de la tabla de dispersión cercano al <NÚMERO>"
-#: lexsup.c:377
+#: lexsup.c:398
msgid "Print option help"
msgstr "Muestra la ayuda de opciones"
-#: lexsup.c:379
+#: lexsup.c:400
msgid "Call SYMBOL at load-time"
-msgstr "Llamar al SÍMBOLO al momento de cargar"
+msgstr "Llama al SÍMBOLO al momento de cargar"
-#: lexsup.c:381
+#: lexsup.c:402
msgid "Write a map file"
-msgstr "Escribir un fichero mapa"
+msgstr "Escribe un fichero mapa"
-#: lexsup.c:383
+#: lexsup.c:404
msgid "Do not define Common storage"
-msgstr "No definir almacenamiento Common"
+msgstr "No define almacenamiento Common"
-#: lexsup.c:385
+#: lexsup.c:406
msgid "Do not demangle symbol names"
-msgstr "No desenredar los nombres de los símbolos"
+msgstr "No desenreda los nombres de los símbolos"
-#: lexsup.c:387
+#: lexsup.c:408
msgid "Use less memory and more disk I/O"
-msgstr "Usar menos memoria y más E/S de disco"
+msgstr "Usa menos memoria y más E/S de disco"
-#: lexsup.c:389
+#: lexsup.c:410
msgid "Do not allow unresolved references in object files"
-msgstr "No permitir referencias sin resolver en ficheros objeto"
+msgstr "No permite referencias sin resolver en ficheros objeto"
-#: lexsup.c:392
+#: lexsup.c:413
msgid "Allow unresolved references in shared libaries"
-msgstr "Permitir referencias sin resolver en bibliotecas compartidas"
+msgstr "Permite referencias sin resolver en bibliotecas compartidas"
-#: lexsup.c:396
+#: lexsup.c:417
msgid "Do not allow unresolved references in shared libs"
-msgstr "No permitir referencias sin resolver en bibliotecas compartidas"
+msgstr "No permite referencias sin resolver en bibliotecas compartidas"
-#: lexsup.c:400
+#: lexsup.c:421
msgid "Allow multiple definitions"
-msgstr "Permitir definiciones múltiples"
+msgstr "Permite definiciones múltiples"
-#: lexsup.c:402
+#: lexsup.c:423
msgid "Disallow undefined version"
-msgstr "No permitir versiones sin definir"
+msgstr "No permite versiones sin definir"
-#: lexsup.c:404
+#: lexsup.c:425
msgid "Create default symbol version"
-msgstr "Crear la versión de símbolo por defecto"
+msgstr "Crea la versión de símbolo por defecto"
-#: lexsup.c:407
+#: lexsup.c:428
msgid "Create default symbol version for imported symbols"
-msgstr "Crear la versión de símbolo por defecto para símbolos importados"
+msgstr "Crea la versión de símbolo por defecto para símbolos importados"
-#: lexsup.c:410
+#: lexsup.c:431
msgid "Don't warn about mismatched input files"
-msgstr "No avisar sobre ficheros de entrada sin coincidencia"
+msgstr "No avisa sobre ficheros de entrada sin coincidencia"
-#: lexsup.c:412
+#: lexsup.c:434
+msgid "Don't warn on finding an incompatible library"
+msgstr "No avisa al encontrar una biblioteca incompatible"
+
+#: lexsup.c:437
msgid "Turn off --whole-archive"
-msgstr "Apagar --whole-archive"
+msgstr "Apaga --whole-archive"
-#: lexsup.c:414
+#: lexsup.c:439
msgid "Create an output file even if errors occur"
-msgstr "Crear un fichero de salida aún si ocurren errores"
+msgstr "Crea un fichero de salida aún si ocurren errores"
-#: lexsup.c:419
+#: lexsup.c:444
msgid ""
"Only use library directories specified on\n"
"\t\t\t\tthe command line"
msgstr ""
-"Utilizar solamente los directorios de bibliotecas\n"
+"Utiliza solamente los directorios de bibliotecas\n"
"\t\t\t\tespecificados en la línea de comandos"
-#: lexsup.c:422
+#: lexsup.c:447
msgid "Specify target of output file"
-msgstr "Especificar el objetivo del fichero de salida"
+msgstr "Especifica el objetivo del fichero de salida"
-#: lexsup.c:425
+#: lexsup.c:450
msgid "Ignored for Linux compatibility"
-msgstr "Ignorado por compatibilidad con Linux"
+msgstr "Se descarta por compatibilidad con Linux"
-#: lexsup.c:428
+#: lexsup.c:453
msgid "Reduce memory overheads, possibly taking much longer"
-msgstr "Reducir las saturaciones de memoria, tal vez tomando más tiempo"
+msgstr "Reduce las saturaciones de memoria, tal vez tomando más tiempo"
-#: lexsup.c:431
+#: lexsup.c:456
msgid "Relax branches on certain targets"
-msgstr "Relajar ramificaciones en ciertos objetivos"
+msgstr "Relaja ramificaciones en ciertos objetivos"
-#: lexsup.c:434
+#: lexsup.c:459
msgid "Keep only symbols listed in FILE"
-msgstr "Conservar solamente los símbolos enlistados en el FICHERO"
+msgstr "Conserva solamente los símbolos enlistados en el FICHERO"
-#: lexsup.c:436
+#: lexsup.c:461
msgid "Set runtime shared library search path"
-msgstr "Establecer la rúta de búsqueda de bibliotecas compartidas en tiempo de ejecución"
+msgstr "Establece la ruta de búsqueda de bibliotecas compartidas en tiempo de ejecución"
-#: lexsup.c:438
+#: lexsup.c:463
msgid "Set link time shared library search path"
-msgstr "Establecer la rúta de búsqueda de bibliotecas compartidas en tiempo de enlace"
+msgstr "Establece la ruta de búsqueda de bibliotecas compartidas en tiempo de enlace"
-#: lexsup.c:441
+#: lexsup.c:466
msgid "Create a shared library"
-msgstr "Crear una biblioteca compartida"
+msgstr "Crea una biblioteca compartida"
-#: lexsup.c:445
+#: lexsup.c:470
msgid "Create a position independent executable"
-msgstr "Crear un ejecutable independiente de posición"
+msgstr "Crea un ejecutable independiente de posición"
-#: lexsup.c:449
+#: lexsup.c:474
msgid "Sort common symbols by size"
-msgstr "Ordenar los símbolos comunes por tamaño"
+msgstr "Ordena los símbolos comunes por tamaño"
-#: lexsup.c:453
+#: lexsup.c:478
msgid "name|alignment"
msgstr "nombre|alineación"
-#: lexsup.c:454
+#: lexsup.c:479
msgid "Sort sections by name or maximum alignment"
-msgstr "Ordenar secciones por nombre o alineación máxima"
+msgstr "Ordena secciones por nombre o alineación máxima"
-#: lexsup.c:456
+#: lexsup.c:481
msgid "COUNT"
msgstr "CUENTA"
-#: lexsup.c:456
+#: lexsup.c:481
msgid "How many tags to reserve in .dynamic section"
-msgstr "Cúantas marcas reservar en la sección .dynamic"
+msgstr "Cúantas marcas reserva en la sección .dynamic"
-#: lexsup.c:459
+#: lexsup.c:484
msgid "[=SIZE]"
msgstr "[=TAMAÑO]"
-#: lexsup.c:459
+#: lexsup.c:484
msgid "Split output sections every SIZE octets"
-msgstr "Dividir las secciones de salida cada TAMAÑO octetos"
+msgstr "Divide las secciones de salida cada TAMAÑO octetos"
-#: lexsup.c:462
+#: lexsup.c:487
msgid "[=COUNT]"
msgstr "[=CUENTA]"
-#: lexsup.c:462
+#: lexsup.c:487
msgid "Split output sections every COUNT relocs"
-msgstr "Dividir las secciones de salida cada CUENTA reubicaciones"
+msgstr "Divide las secciones de salida cada CUENTA reubicaciones"
-#: lexsup.c:465
+#: lexsup.c:490
msgid "Print memory usage statistics"
-msgstr "Mostrar las estadísticas de uso de memoria"
+msgstr "Muestra las estadísticas de uso de memoria"
-#: lexsup.c:467
+#: lexsup.c:492
msgid "Display target specific options"
-msgstr "Mostrar las opciones específicas del objetivo"
+msgstr "Muestra las opciones específicas del objetivo"
-#: lexsup.c:469
+#: lexsup.c:494
msgid "Do task level linking"
-msgstr "Enlazar a nivel de tarea"
+msgstr "Enlaza a nivel de tarea"
-#: lexsup.c:471
+#: lexsup.c:496
msgid "Use same format as native linker"
-msgstr "Usar el mismo formato que el enlazador nativo"
+msgstr "Usa el mismo formato que el enlazador nativo"
-#: lexsup.c:473
+#: lexsup.c:498
msgid "SECTION=ADDRESS"
msgstr "SECCIÓN=DIRECCIÓN"
-#: lexsup.c:473
+#: lexsup.c:498
msgid "Set address of named section"
-msgstr "Establecer la dirección de la sección nombrada"
+msgstr "Establece la dirección de la sección nombrada"
-#: lexsup.c:476
+#: lexsup.c:501
msgid "Set address of .bss section"
-msgstr "Establecer la dirección de la sección .bss"
+msgstr "Establece la dirección de la sección .bss"
-#: lexsup.c:478
+#: lexsup.c:503
msgid "Set address of .data section"
-msgstr "Establecer la dirección de la sección .data"
+msgstr "Establece la dirección de la sección .data"
-#: lexsup.c:480
+#: lexsup.c:505
msgid "Set address of .text section"
-msgstr "Establecer la dirección de la sección .text"
+msgstr "Establece la dirección de la sección .text"
-#: lexsup.c:483
+#: lexsup.c:508
msgid ""
"How to handle unresolved symbols. <method> is:\n"
"\t\t\t\tignore-all, report-all, ignore-in-object-files,\n"
@@ -1669,89 +1718,105 @@ msgstr ""
"\t\t\t\tignore-all, report-all, ignore-in-object-files,\n"
"\t\t\t\tignore-in-shared-libs"
-#: lexsup.c:487
+#: lexsup.c:512
msgid "Output lots of information during link"
-msgstr "Mostrar mucha información durante el enlace"
+msgstr "Muestra mucha información durante el enlace"
-#: lexsup.c:491
+#: lexsup.c:516
msgid "Read version information script"
-msgstr "Leer la información de la versión del guión"
+msgstr "Lee la información de la versión del guión"
-#: lexsup.c:494
+#: lexsup.c:519
msgid ""
"Take export symbols list from .exports, using\n"
"\t\t\t\tSYMBOL as the version."
msgstr ""
-"Tomar la lista de exportación de símbolos de .exports, usando\n"
+"Toma la lista de exportación de símbolos de .exports, usando\n"
"\t\t\tel SÍMBOLO como la versión."
-#: lexsup.c:497
+#: lexsup.c:522
+msgid "Add data symbols to dynamic list"
+msgstr "Agrega símbolos de datos a la lista dinámica"
+
+#: lexsup.c:524
+msgid "Use C++ operator new/delete dynamic list"
+msgstr "Usa la lista dinámica de los operadores de C++ new/delete"
+
+#: lexsup.c:526
+msgid "Use C++ typeinfo dynamic list"
+msgstr "Usa la lista dinámica de tipo de dato de C++"
+
+#: lexsup.c:528
+msgid "Read dynamic list"
+msgstr "Lee la lista dinámica"
+
+#: lexsup.c:530
msgid "Warn about duplicate common symbols"
-msgstr "Avisar sobre símbolos comunes duplicados"
+msgstr "Avisa sobre símbolos comunes duplicados"
-#: lexsup.c:499
+#: lexsup.c:532
msgid "Warn if global constructors/destructors are seen"
-msgstr "Avisar si se ven constructores/destructores globales"
+msgstr "Avisa si se ven constructores/destructores globales"
-#: lexsup.c:502
+#: lexsup.c:535
msgid "Warn if the multiple GP values are used"
-msgstr "Avisar si se usan los valores múltiples GP"
+msgstr "Avisa si se usan los valores múltiples GP"
-#: lexsup.c:504
+#: lexsup.c:537
msgid "Warn only once per undefined symbol"
-msgstr "Avisar sólo una vez por cada símbolo sin definir"
+msgstr "Avisa sólo una vez por cada símbolo sin definir"
-#: lexsup.c:506
+#: lexsup.c:539
msgid "Warn if start of section changes due to alignment"
-msgstr "Avisar si el inicio de la sección cambia debido a la alineación"
+msgstr "Avisa si el inicio de la sección cambia debido a la alineación"
-#: lexsup.c:509
+#: lexsup.c:542
msgid "Warn if shared object has DT_TEXTREL"
-msgstr "Avisar si el objeto compartido tiene DT_TEXTREL"
+msgstr "Avisa si el objeto compartido tiene DT_TEXTREL"
-#: lexsup.c:513
+#: lexsup.c:546
msgid "Report unresolved symbols as warnings"
-msgstr "Reportar símbolos sin resolver como avisos"
+msgstr "Reporta símbolos sin resolver como avisos"
-#: lexsup.c:516
+#: lexsup.c:549
msgid "Report unresolved symbols as errors"
-msgstr "Reportar símbolos sin resolver como errores"
+msgstr "Reporta símbolos sin resolver como errores"
-#: lexsup.c:518
+#: lexsup.c:551
msgid "Include all objects from following archives"
-msgstr "Incluir todos los objetos de los siguientes ficheros"
+msgstr "Incluye todos los objetos de los siguientes ficheros"
-#: lexsup.c:521
+#: lexsup.c:554
msgid "Use wrapper functions for SYMBOL"
-msgstr "Usar funciones de envoltura para el SÍMBOLO"
+msgstr "Usa funciones de envoltura para el SÍMBOLO"
-#: lexsup.c:668
+#: lexsup.c:701
msgid "%P: unrecognized option '%s'\n"
-msgstr "%P: opción `%s' no reconocida\n"
+msgstr "%P: no se reconoce la opción `%s'\n"
-#: lexsup.c:670
+#: lexsup.c:705
msgid "%P%F: use the --help option for usage information\n"
msgstr "%P%F: use la opción --help para información de modo de empleo\n"
-#: lexsup.c:688
+#: lexsup.c:723
msgid "%P%F: unrecognized -a option `%s'\n"
-msgstr "%P%F: opción -a `%s' no reconocida\n"
+msgstr "%P%F: no se reconoce la opción -a `%s'\n"
-#: lexsup.c:701
+#: lexsup.c:736
msgid "%P%F: unrecognized -assert option `%s'\n"
-msgstr "%P%F: opción -assert `%s' no reconocida\n"
+msgstr "%P%F: no se reconoce la opción -assert `%s'\n"
-#: lexsup.c:744
+#: lexsup.c:779
msgid "%F%P: unknown demangling style `%s'"
msgstr "%F%P: estilo de desenredo `%s' desconocido"
-#: lexsup.c:806
+#: lexsup.c:841
msgid "%P%F: invalid number `%s'\n"
msgstr "%P%F: número `%s' inválido\n"
-#: lexsup.c:898
+#: lexsup.c:939
msgid "%P%F: bad --unresolved-symbols option: %s\n"
-msgstr "%P%F: opción --unresolved-symbols no reconocida: %s\n"
+msgstr "%P%F: no se reconoce la opción --unresolved-symbols: %s\n"
#. This can happen if the user put "-rpath,a" on the command
#. line. (Or something similar. The comma is important).
@@ -1761,168 +1826,171 @@ msgstr "%P%F: opción --unresolved-symbols no reconocida: %s\n"
#. an error message here. We cannot just make this a warning,
#. increment optind, and continue because getopt is too confused
#. and will seg-fault the next time around.
-#: lexsup.c:969
+#: lexsup.c:1013
msgid "%P%F: bad -rpath option\n"
msgstr "%P%F: opción -rpath errónea\n"
-#: lexsup.c:1081
+#: lexsup.c:1124
msgid "%P%F: -shared not supported\n"
-msgstr "%P%F: -shared no tiene soporte\n"
+msgstr "%P%F: no se admite -shared\n"
-#: lexsup.c:1090
+#: lexsup.c:1133
msgid "%P%F: -pie not supported\n"
-msgstr "%P%F: -pie no tiene soporte\n"
+msgstr "%P%F: no se admite -pie\n"
-#: lexsup.c:1100
+#: lexsup.c:1143
msgid "name"
msgstr "nombre"
-#: lexsup.c:1102
+#: lexsup.c:1145
msgid "alignment"
msgstr "alineación"
-#: lexsup.c:1105
+#: lexsup.c:1148
msgid "%P%F: invalid section sorting option: %s\n"
msgstr "%P%F: opción de ordenado de sección inválida: %s\n"
-#: lexsup.c:1131
+#: lexsup.c:1180
msgid "%P%F: invalid argument to option \"--section-start\"\n"
msgstr "%P%F: argumento inválido para la opción \"--section-start\"\n"
-#: lexsup.c:1138
+#: lexsup.c:1187
msgid "%P%F: missing argument(s) to option \"--section-start\"\n"
msgstr "%P%F: falta(n) argumento(s) para la opción \"--section-start\"\n"
-#: lexsup.c:1312
+#: lexsup.c:1398
msgid "%P%F: may not nest groups (--help for usage)\n"
msgstr "%P%F: no se pueden anidar grupos (--help para modo de empleo)\n"
-#: lexsup.c:1319
+#: lexsup.c:1405
msgid "%P%F: group ended before it began (--help for usage)\n"
msgstr "%P%F: el grupo terminó antes de empezar (--help para modo de empleo)\n"
-#: lexsup.c:1347
+#: lexsup.c:1433
msgid "%P%X: --hash-size needs a numeric argument\n"
msgstr "%P%X: --hash-size necesita un argumento numérico\n"
-#: lexsup.c:1398 lexsup.c:1411
+#: lexsup.c:1484 lexsup.c:1497
msgid "%P%F: invalid hex number `%s'\n"
msgstr "%P%F: número hexadecimal `%s' inválido\n"
-#: lexsup.c:1447
+#: lexsup.c:1533
#, c-format
msgid "Usage: %s [options] file...\n"
msgstr "Modo de empleo: %s [opciones] fichero...\n"
-#: lexsup.c:1449
+#: lexsup.c:1535
#, c-format
msgid "Options:\n"
msgstr "Opciones:\n"
-#: lexsup.c:1527
+#: lexsup.c:1613
#, c-format
msgid " @FILE"
msgstr " @FICHERO"
-#: lexsup.c:1530
+#: lexsup.c:1616
#, c-format
msgid "Read options from FILE\n"
msgstr "Lee opciones del FICHERO\n"
#. Note: Various tools (such as libtool) depend upon the
#. format of the listings below - do not change them.
-#: lexsup.c:1535
+#: lexsup.c:1621
#, c-format
msgid "%s: supported targets:"
-msgstr "%s: objetivos con soporte:"
+msgstr "%s: objetivos admitidos:"
-#: lexsup.c:1543
+#: lexsup.c:1629
#, c-format
msgid "%s: supported emulations: "
-msgstr "%s: emulaciones con soporte: "
+msgstr "%s: emulaciones admitidas: "
-#: lexsup.c:1548
+#: lexsup.c:1634
#, c-format
msgid "%s: emulation specific options:\n"
msgstr "%s: opciones específicas de emulación:\n"
-#: lexsup.c:1552
+#: lexsup.c:1639
#, c-format
msgid "Report bugs to %s\n"
-msgstr "Reportar bichos a %s\n"
+msgstr "Reporte bichos a %s\n"
#: mri.c:291
msgid "%P%F: unknown format type %s\n"
msgstr "%P%F: tipo de formato %s desconocido\n"
-#: pe-dll.c:303
+#: pe-dll.c:367
#, c-format
msgid "%XUnsupported PEI architecture: %s\n"
-msgstr "%XArquitectura PEI sin soporte: %s\n"
+msgstr "%XNo se admite la arquitectura PEI: %s\n"
-#: pe-dll.c:604
+#: pe-dll.c:673
#, c-format
msgid "%XCannot export %s: invalid export name\n"
msgstr "%XNo se puede exportar %s: nombre de exportación inválido\n"
-#: pe-dll.c:657
+#: pe-dll.c:729
#, c-format
msgid "%XError, duplicate EXPORT with ordinals: %s (%d vs %d)\n"
msgstr "%XError, EXPORT duplicado con ordinales: %s (%d vs %d)\n"
-#: pe-dll.c:664
+#: pe-dll.c:736
#, c-format
msgid "Warning, duplicate EXPORT: %s\n"
msgstr "Aviso, EXPORT duplicado: %s\n"
-#: pe-dll.c:751
+#: pe-dll.c:823
#, c-format
msgid "%XCannot export %s: symbol not defined\n"
msgstr "%XNo se puede exportar %s: símbolo no definido\n"
-#: pe-dll.c:757
+#: pe-dll.c:829
#, c-format
msgid "%XCannot export %s: symbol wrong type (%d vs %d)\n"
msgstr "%XNo se puede exportar %s: tipo erróneo del símbolo (%d vs %d)\n"
-#: pe-dll.c:764
+#: pe-dll.c:836
#, c-format
msgid "%XCannot export %s: symbol not found\n"
msgstr "%XNo se puede exportar %s: no se encuentra el símbolo\n"
-#: pe-dll.c:877
+#: pe-dll.c:949
#, c-format
msgid "%XError, ordinal used twice: %d (%s vs %s)\n"
msgstr "%XError, ordinal utilizado dos veces: %d (%s vs %s)\n"
-#: pe-dll.c:1219
+#: pe-dll.c:1297
#, c-format
msgid "%XError: %d-bit reloc in dll\n"
msgstr "%XError: reubicación de %d-bit en la dll\n"
-#: pe-dll.c:1347
+#: pe-dll.c:1425
#, c-format
msgid "%s: Can't open output def file %s\n"
msgstr "%s: No se puede abrir el fichero por defecto de salida %s\n"
-#: pe-dll.c:1490
+#: pe-dll.c:1568
#, c-format
msgid "; no contents available\n"
msgstr "; no hay contenido disponible\n"
-#: pe-dll.c:2252
+#: pe-dll.c:2364
msgid "%C: variable '%T' can't be auto-imported. Please read the documentation for ld's --enable-auto-import for details.\n"
msgstr "%C: no se puede auto-importar la variable '%T'. Por favor lea la documentación para --enable-auto-import de ld para más detalles.\n"
-#: pe-dll.c:2282
+#: pe-dll.c:2394
#, c-format
msgid "%XCan't open .lib file: %s\n"
msgstr "%XNo se puede abrir el fichero .lib: %s\n"
-#: pe-dll.c:2287
+#: pe-dll.c:2399
#, c-format
msgid "Creating library file: %s\n"
-msgstr "Creando el fichero de biblioteca: %s\n"
+msgstr "Se crea el fichero de biblioteca: %s\n"
+
+#~ msgid "%F%S non constant expression for %s\n"
+#~ msgstr "%F%S expresión no constante para %s\n"
#~ msgid "%P%F: out of memory during initialization"
#~ msgstr "%P%F: memoria agotada durante la inicialización"
1' href='#n3591'>3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662
/* gasp.c - Gnu assembler preprocessor main program.
   Copyright (C) 1994, 1995 Free Software Foundation, Inc.

   Written by Steve and Judy Chamberlain of Cygnus Support,
      sac@cygnus.com

   This file is part of GASP, the GNU Assembler Preprocessor.

   GASP 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 2, or (at your option)
   any later version.

   GASP 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 GASP; see the file COPYING.  If not, write to the Free
   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA. */

/*

This program translates the input macros and stuff into a form
suitable for gas to consume.


  gasp [-sdhau] [-c char] [-o <outfile>] <infile>*

  -s copy source to output
  -c <char> comments are started with <char> instead of !
  -u allow unreasonable stuff
  -p print line numbers
  -d print debugging stats
  -s semi colons start comments
  -a use alternate syntax
     Pseudo ops can start with or without a .
     Labels have to be in first column.
  -I specify include dir
    Macro arg parameters subsituted by name, don't need the &.
     String can start with ' too.
     Strings can be surrounded by <..>
     A %<exp> in a string evaluates the expression 
     Literal char in a string with !


*/

#include "config.h"

#include <stdio.h>
#include <string.h>
#include <getopt.h>
#include <ctype.h>

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#ifdef NEED_MALLOC_DECLARATION
extern char *malloc ();
#endif

#include "ansidecl.h"
#include "libiberty.h"
#include "sb.h"
#include "macro.h"

char *program_version = "1.2";

#define MAX_INCLUDES 30		/* Maximum include depth */
#define MAX_REASONABLE 1000	/* Maximum number of expansions */

int unreasonable;		/* -u on command line */
int stats;			/* -d on command line */
int print_line_number;		/* -p flag on command line */
int copysource;			/* -c flag on command line */
int warnings;			/* Number of WARNINGs generated so far. */
int errors;			/* Number of ERRORs generated so far. */
int fatals;			/* Number of fatal ERRORs generated so far (either 0 or 1). */
int alternate = 0;              /* -a on command line */
int mri = 0;			/* -M on command line */
char comment_char = '!';
int radix = 10;			/* Default radix */

int had_end; /* Seen .END */

/* The output stream */
FILE *outfile;

/* the attributes of each character are stored as a bit pattern
   chartype, which gives us quick tests. */


#define FIRSTBIT 1
#define NEXTBIT  2
#define SEPBIT   4
#define WHITEBIT 8
#define COMMENTBIT 16
#define BASEBIT  32
#define ISCOMMENTCHAR(x) (chartype[(unsigned)(x)] & COMMENTBIT)
#define ISFIRSTCHAR(x)  (chartype[(unsigned)(x)] & FIRSTBIT)
#define ISNEXTCHAR(x)   (chartype[(unsigned)(x)] & NEXTBIT)
#define ISSEP(x)        (chartype[(unsigned)(x)] & SEPBIT)
#define ISWHITE(x)      (chartype[(unsigned)(x)] & WHITEBIT)
#define ISBASE(x)       (chartype[(unsigned)(x)] & BASEBIT)
static char chartype[256];


/* Conditional assembly uses the `ifstack'.  Each aif pushes another
   entry onto the stack, and sets the on flag if it should.  The aelse
   sets hadelse, and toggles on.  An aend pops a level.  We limit to
   100 levels of nesting, not because we're facists pigs with read
   only minds, but because more than 100 levels of nesting is probably
   a bug in the user's macro structure.  */

#define IFNESTING 100
struct
  {
    int on;			/* is the level being output */
    int hadelse;		/* has an aelse been seen */
  }
ifstack[IFNESTING];
int ifi;

/* The final and intermediate results of expression evaluation are kept in
   exp_t's.  Note that a symbol is not an sb, but a pointer into the input
   line.  It must be coped somewhere safe before the next line is read in. */

typedef struct
  {
    char *name;
    int len;
  }
symbol;

typedef struct
  {
    int value;			/* constant part */
    symbol add_symbol;		/* name part */
    symbol sub_symbol;		/* name part */
  }
exp_t;


/* Hashing is done in a pretty standard way.  A hash_table has a
   pointer to a vector of pointers to hash_entrys, and the size of the
   vector.  A hash_entry contains a union of all the info we like to
   store in hash table.  If there is a hash collision, hash_entries
   with the same hash are kept in a chain. */

/* What the data in a hash_entry means */
typedef enum
  {
    hash_integer,		/* name->integer mapping */
    hash_string,		/* name->string mapping */
    hash_macro,			/* name is a macro */
    hash_formal			/* name is a formal argument */
  } hash_type;

typedef struct hs
  {
    sb key;			/* symbol name */
    hash_type type;		/* symbol meaning */
    union
      {
	sb s;
	int i;
	struct macro_struct *m;
	struct formal_struct *f;
      } value;
    struct hs *next;		/* next hash_entry with same hash key */
  } hash_entry;

typedef struct
  {
    hash_entry **table;
    int size;
  } hash_table;


/* Structures used to store macros. 

   Each macro knows its name and included text.  It gets built with a
   list of formal arguments, and also keeps a hash table which points
   into the list to speed up formal search.  Each formal knows its
   name and its default value.  Each time the macro is expanded, the
   formals get the actual values attatched to them. */

/* describe the formal arguments to a macro */

typedef struct formal_struct
  {
    struct formal_struct *next;	/* next formal in list */
    sb name;			/* name of the formal */
    sb def;			/* the default value */
    sb actual;			/* the actual argument (changed on each expansion) */
    int index;			/* the index of the formal 0..formal_count-1 */
  }
formal_entry;

/* describe the macro. */

typedef struct macro_struct
  {
    sb sub;			/* substitution text. */
    int formal_count;		/* number of formal args. */
    formal_entry *formals;	/* pointer to list of formal_structs */
    hash_table formal_hash;	/* hash table of formals. */
  }
macro_entry;

/* how we nest files and expand macros etc.

   we keep a stack of of include_stack structs.  each include file
   pushes a new level onto the stack.  we keep an sb with a pushback
   too.  unget chars are pushed onto the pushback sb, getchars first
   checks the pushback sb before reading from the input stream.

   small things are expanded by adding the text of the item onto the
   pushback sb.  larger items are grown by pushing a new level and
   allocating the entire pushback buf for the item.  each time
   something like a macro is expanded, the stack index is changed. we
   can then perform an exitm by popping all entries off the stack with
   the same stack index.  if we're being reasonable, we can detect
   recusive expansion by checking the index is reasonably small.
 */

typedef enum
  {
    include_file, include_repeat, include_while, include_macro
  } include_type;

struct include_stack
  {
    sb pushback;		/* current pushback stream */
    int pushback_index;		/* next char to read from stream */
    FILE *handle;		/* open file */
    sb name;			/* name of file */
    int linecount;		/* number of lines read so far */
    include_type type;
    int index;			/* index of this layer */
  }
include_stack[MAX_INCLUDES];

struct include_stack *sp;
#define isp (sp - include_stack)

/* Include file list */

typedef struct include_path 
{
  struct include_path *next;
  sb path;
}  include_path;

include_path *paths_head;
include_path *paths_tail;


static void quit PARAMS ((void));
static void hash_new_table PARAMS ((int, hash_table *));
static int hash PARAMS ((sb *));
static hash_entry *hash_create PARAMS ((hash_table *, sb *));
static void hash_add_to_string_table PARAMS ((hash_table *, sb *, sb *, int));
static void hash_add_to_int_table PARAMS ((hash_table *, sb *, int));
static hash_entry *hash_lookup PARAMS ((hash_table *, sb *));
static void checkconst PARAMS ((int, exp_t *));
static int sb_strtol PARAMS ((int, sb *, int, int *));
static int level_0 PARAMS ((int, sb *, exp_t *));
static int level_1 PARAMS ((int, sb *, exp_t *));
static int level_2 PARAMS ((int, sb *, exp_t *));
static int level_3 PARAMS ((int, sb *, exp_t *));
static int level_4 PARAMS ((int, sb *, exp_t *));
static int level_5 PARAMS ((int, sb *, exp_t *));
static int exp_parse PARAMS ((int, sb *, exp_t *));
static void exp_string PARAMS ((exp_t *, sb *));
static int exp_get_abs PARAMS ((const char *, int, sb *, int *));
#if 0
static void strip_comments PARAMS ((sb *));
#endif
static void unget PARAMS ((int));
static void include_buf PARAMS ((sb *, sb *, include_type, int));
static void include_print_where_line PARAMS ((FILE *));
static void include_print_line PARAMS ((FILE *));
static int get_line PARAMS ((sb *));
static int grab_label PARAMS ((sb *, sb *));
static void change_base PARAMS ((int, sb *, sb *));
static void do_end PARAMS ((sb *));
static void do_assign PARAMS ((int, int, sb *));
static void do_radix PARAMS ((sb *));
static int get_opsize PARAMS ((int, sb *, int *));
static int eol PARAMS ((int, sb *));
static void do_data PARAMS ((int, sb *, int));
static void do_datab PARAMS ((int, sb *));
static void do_align PARAMS ((int, sb *));
static void do_res PARAMS ((int, sb *, int));
static void do_export PARAMS ((sb *));
static void do_print PARAMS ((int, sb *));
static void do_heading PARAMS ((int, sb *));
static void do_page PARAMS ((void));
static void do_form PARAMS ((int, sb *));
static int get_any_string PARAMS ((int, sb *, sb *, int, int));
static int skip_openp PARAMS ((int, sb *));
static int skip_closep PARAMS ((int, sb *));
static int dolen PARAMS ((int, sb *, sb *));
static int doinstr PARAMS ((int, sb *, sb *));
static int dosubstr PARAMS ((int, sb *, sb *));
static void process_assigns PARAMS ((int, sb *, sb *));
static int get_and_process PARAMS ((int, sb *, sb *));
static void process_file PARAMS ((void));
static void free_old_entry PARAMS ((hash_entry *));
static void do_assigna PARAMS ((int, sb *));
static void do_assignc PARAMS ((int, sb *));
static void do_reg PARAMS ((int, sb *));
static int condass_lookup_name PARAMS ((sb *, int, sb *, int));
static int whatcond PARAMS ((int, sb *, int *));
static int istrue PARAMS ((int, sb *));
static void do_aif PARAMS ((int, sb *));
static void do_aelse PARAMS ((void));
static void do_aendi PARAMS ((void));
static int condass_on PARAMS ((void));
static void do_if PARAMS ((int, sb *, int));
static int get_mri_string PARAMS ((int, sb *, sb *, int));
static void do_ifc PARAMS ((int, sb *, int));
static void do_aendr PARAMS ((void));
static void do_awhile PARAMS ((int, sb *));
static void do_aendw PARAMS ((void));
static void do_exitm PARAMS ((void));
static void do_arepeat PARAMS ((int, sb *));
static void do_endm PARAMS ((void));
static void do_irp PARAMS ((int, sb *, int));
static void do_local PARAMS ((int, sb *));
static void do_macro PARAMS ((int, sb *));
static int macro_op PARAMS ((int, sb *));
static int getstring PARAMS ((int, sb *, sb *));
static void do_sdata PARAMS ((int, sb *, int));
static void do_sdatab PARAMS ((int, sb *));
static int new_file PARAMS ((const char *));
static void do_include PARAMS ((int, sb *));
static void include_pop PARAMS ((void));
static int get PARAMS ((void));
static int linecount PARAMS ((void));
static int include_next_index PARAMS ((void));
static void chartype_init PARAMS ((void));
static int process_pseudo_op PARAMS ((int, sb *, sb *));
static void add_keyword PARAMS ((const char *, int));
static void process_init PARAMS ((void));
static void do_define PARAMS ((const char *));
static void show_usage PARAMS ((FILE *, int));
static void show_help PARAMS ((void));

#define FATAL(x) \
  do { include_print_where_line (stderr); fprintf x ; fatals++; quit(); } while(0) 
#define ERROR(x) \
  do { include_print_where_line (stderr); fprintf x; errors++; } while(0)
#define WARNING(x) \
  do { include_print_where_line (stderr); fprintf x; warnings++;} while(0) 



/* exit the program and return the right ERROR code. */
static void
quit ()
{
  int exitcode;
  if (fatals + errors)
    exitcode = 1;
  else
    exitcode = 0;

  if (stats) 
    {
      int i;
      for (i = 0; i < sb_max_power_two; i++) 
	{
	  fprintf (stderr, "strings size %8d : %d\n", 1<<i, string_count[i]);
	}
    }
  exit (exitcode);
}

/* hash table maintenance. */

/* build a new hash table with size buckets, and fill in the info at ptr. */

static void
hash_new_table (size, ptr)
     int size;
     hash_table *ptr;
{
  int i;
  ptr->size = size;
  ptr->table = (hash_entry **) xmalloc (size * (sizeof (hash_entry *)));
  /* Fill with null-pointer, not zero-bit-pattern.  */
  for (i = 0; i < size; i++)
    ptr->table[i] = 0;
}

/* calculate and return the hash value of the sb at key. */

static int
hash (key)
     sb *key;
{
  int k = 0x1234;
  int i;
  char *p = key->ptr;
  for (i = 0; i < key->len; i++)
    {
      k ^= (k << 2) ^ *p;
      p++;
    }
  return k & 0xf0fff;
}

/* lookup key in hash_table tab, if present, then return it, otherwise
   build a new one and fill it with hash_integer. */

static
hash_entry *
hash_create (tab, key)
     hash_table *tab;
     sb *key;
{
  int k = hash (key) % tab->size;
  hash_entry *p;
  hash_entry **table = tab->table;

  p = table[k];

  while (1)
    {
      if (!p)
	{
	  hash_entry *n = (hash_entry *) xmalloc (sizeof (hash_entry));
	  n->next = table[k];
	  sb_new (&n->key);
	  sb_add_sb (&n->key, key);
	  table[k] = n;
	  n->type = hash_integer;
	  return n;
	}
      if (strncmp (table[k]->key.ptr, key->ptr, key->len) == 0)
	{
	  return p;
	}
      p = p->next;
    }
}

/* add sb name with key into hash_table tab.  if replacing old value
   and again, then ERROR. */

static
void
hash_add_to_string_table (tab, key, name, again)
     hash_table *tab;
     sb *key;
     sb *name;
     int again;
{
  hash_entry *ptr = hash_create (tab, key);
  if (ptr->type == hash_integer)
    {
      sb_new (&ptr->value.s);
    }
  if (ptr->value.s.len)
    {
      if (!again)
	ERROR ((stderr, "redefintion not allowed"));
    }

  ptr->type = hash_string;
  sb_reset (&ptr->value.s);
  
  sb_add_sb (&ptr->value.s, name);
}

/* add integer name to hash_table tab with sb key. */

static
void
hash_add_to_int_table (tab, key, name)
     hash_table *tab;
     sb *key;
     int name;
{
  hash_entry *ptr = hash_create (tab, key);
  ptr->value.i = name;
}

/* lookup sb key in hash_table tab.  if found return hash_entry result,
   else 0. */
   
static
hash_entry *
hash_lookup (tab, key)
     hash_table *tab;
     sb *key;
{
  int k = hash (key) % tab->size;
  hash_entry **table = tab->table;
  hash_entry *p = table[k];
  while (p)
    {
      if (p->key.len == key->len
	  && strncmp (p->key.ptr, key->ptr, key->len) == 0)
	return p;
      p = p->next;
    }
  return 0;
}


/* expressions

   are handled in a really simple recursive decent way. each bit of
   the machine takes an index into an sb and a pointer to an exp_t,
   modifies the *exp_t and returns the index of the first character
   past the part of the expression parsed.

 expression precedence:
  ( )
 unary + - ~
  * /
  + -
  &
  | ~

*/


/* make sure that the exp_t at term is constant, if not the give the op ERROR. */

static
void
checkconst (op, term)
     int op;
     exp_t *term;
{
  if (term->add_symbol.len
      || term->sub_symbol.len)
    {
      ERROR ((stderr, "the %c operator cannot take non-absolute arguments.\n", op));
    }
}

/* turn the number in string at idx into a number of base,
   fill in ptr and return the index of the first character not in the
   number. */

static
int
sb_strtol (idx, string, base, ptr)
     int idx;
     sb *string;
     int base;
     int *ptr;
{
  int value = 0;
  idx = sb_skip_white (idx, string);

  while (idx < string->len)
    {
      int ch = string->ptr[idx];
      int dig = 0;
      if (isdigit (ch))
	dig = ch - '0';
      else if (ch >= 'a' && ch <= 'f')
	dig = ch - 'a' + 10;
      else if (ch >= 'A' && ch <= 'F')
	dig = ch - 'A' + 10;
      else
	break;

      if (dig >= base)
	break;

      value = value * base + dig;
      idx++;
    }
  *ptr = value;
  return idx;
}

static int
level_0 (idx, string, lhs)
     int idx;
     sb *string;
     exp_t *lhs;
{
  lhs->add_symbol.len = 0;
  lhs->add_symbol.name = 0;

  lhs->sub_symbol.len = 0;
  lhs->sub_symbol.name = 0;

  idx = sb_skip_white (idx, string);

  lhs->value = 0;

  if (isdigit (string->ptr[idx]))
    {
      idx = sb_strtol (idx, string, 10, &lhs->value);
    }
  else if (ISFIRSTCHAR (string->ptr[idx]))
    {
      int len = 0;
      lhs->add_symbol.name = string->ptr + idx;
      while (idx < string->len && ISNEXTCHAR (string->ptr[idx]))
	{
	  idx++;
	  len++;
	}
      lhs->add_symbol.len = len;
    }
  else if (string->ptr[idx] == '"')
    {
      sb acc;
      sb_new (&acc);
      ERROR ((stderr, "string where expression expected.\n"));
      idx = getstring (idx, string, &acc);
      sb_kill (&acc);
    }
  else
    {
      ERROR ((stderr, "can't find primary in expression.\n"));
      idx++;
    }
  return sb_skip_white (idx, string);
}



static int
level_1 (idx, string, lhs)
     int idx;
     sb *string;
     exp_t *lhs;
{
  idx = sb_skip_white (idx, string);

  switch (string->ptr[idx])
    {
    case '+':
      idx = level_1 (idx + 1, string, lhs);
      break;
    case '~':
      idx = level_1 (idx + 1, string, lhs);
      checkconst ('~', lhs);
      lhs->value = ~lhs->value;
      break;
    case '-':
      {
	symbol t;
	idx = level_1 (idx + 1, string, lhs);
	lhs->value = -lhs->value;
	t = lhs->add_symbol;
	lhs->add_symbol = lhs->sub_symbol;
	lhs->sub_symbol = t;
	break;
      }
    case '(':
      idx++;
      idx = level_5 (sb_skip_white (idx, string), string, lhs);
      if (string->ptr[idx] != ')')
	ERROR ((stderr, "misplaced closing parens.\n"));
      else
	idx++;
      break;
    default:
      idx = level_0 (idx, string, lhs);
      break;
    }
  return sb_skip_white (idx, string);
}

static int
level_2 (idx, string, lhs)
     int idx;
     sb *string;
     exp_t *lhs;
{
  exp_t rhs;

  idx = level_1 (idx, string, lhs);

  while (idx < string->len && (string->ptr[idx] == '*'
			       || string->ptr[idx] == '/'))
    {
      char op = string->ptr[idx++];
      idx = level_1 (idx, string, &rhs);
      switch (op)
	{
	case '*':
	  checkconst ('*', lhs);
	  checkconst ('*', &rhs);
	  lhs->value *= rhs.value;
	  break;
	case '/':
	  checkconst ('/', lhs);
	  checkconst ('/', &rhs);
	  if (rhs.value == 0)
	    ERROR ((stderr, "attempt to divide by zero.\n"));
	  else
	    lhs->value /= rhs.value;
	  break;
	}
    }
  return sb_skip_white (idx, string);
}


static int
level_3 (idx, string, lhs)
     int idx;
     sb *string;
     exp_t *lhs;
{
  exp_t rhs;

  idx = level_2 (idx, string, lhs);

  while (idx < string->len
	 && (string->ptr[idx] == '+'
	     || string->ptr[idx] == '-'))
    {
      char op = string->ptr[idx++];
      idx = level_2 (idx, string, &rhs);
      switch (op)
	{
	case '+':
	  lhs->value += rhs.value;
	  if (lhs->add_symbol.name && rhs.add_symbol.name)
	    {
	      ERROR ((stderr, "can't add two relocatable expressions\n"));
	    }
	  /* change nn+symbol to symbol + nn */
	  if (rhs.add_symbol.name)
	    {
	      lhs->add_symbol = rhs.add_symbol;
	    }
	  break;
	case '-':
	  lhs->value -= rhs.value;
	  lhs->sub_symbol = rhs.add_symbol;
	  break;
	}
    }
  return sb_skip_white (idx, string);
}

static int
level_4 (idx, string, lhs)
     int idx;
     sb *string;
     exp_t *lhs;
{
  exp_t rhs;

  idx = level_3 (idx, string, lhs);

  while (idx < string->len &&
	 string->ptr[idx] == '&')
    {
      char op = string->ptr[idx++];
      idx = level_3 (idx, string, &rhs);
      switch (op)
	{
	case '&':
	  checkconst ('&', lhs);
	  checkconst ('&', &rhs);
	  lhs->value &= rhs.value;
	  break;
	}
    }
  return sb_skip_white (idx, string);
}

static int
level_5 (idx, string, lhs)
     int idx;
     sb *string;
     exp_t *lhs;
{
  exp_t rhs;

  idx = level_4 (idx, string, lhs);

  while (idx < string->len
	 && (string->ptr[idx] == '|' || string->ptr[idx] == '~'))
    {
      char op = string->ptr[idx++];
      idx = level_4 (idx, string, &rhs);
      switch (op)
	{
	case '|':
	  checkconst ('|', lhs);
	  checkconst ('|', &rhs);
	  lhs->value |= rhs.value;
	  break;
	case '~':
	  checkconst ('~', lhs);
	  checkconst ('~', &rhs);
	  lhs->value ^= rhs.value;
	  break;
	}
    }
  return sb_skip_white (idx, string);
}


/* parse the expression at offset idx into string, fill up res with
   the result. return the index of the first char past the expression.
   */

static int
exp_parse (idx, string, res)
     int idx;
     sb *string;
     exp_t *res;
{
  return level_5 (sb_skip_white (idx, string), string, res);
}


/* turn the expression at exp into text and glue it onto the end of
   string. */

static void
exp_string (exp, string)
     exp_t *exp;
     sb *string;
{
  int np = 0;
  int ad = 0;
  sb_reset (string);

  if (exp->add_symbol.len)
    {
      sb_add_buffer (string, exp->add_symbol.name, exp->add_symbol.len);
      np = 1;
      ad = 1;
    }
  if (exp->value)
    {
      char buf[20];
      if (np)
	sb_add_char (string, '+');
      sprintf (buf, "%d", exp->value);
      sb_add_string (string, buf);
      np = 1;
      ad = 1;
    }
  if (exp->sub_symbol.len)
    {
      sb_add_char (string, '-');
      sb_add_buffer (string, exp->add_symbol.name, exp->add_symbol.len);
      np = 0;
      ad = 1;
    }

  if (!ad)
    sb_add_char (string, '0');
}


/* parse the expression at offset idx into sb in, return the value in val.  
   if the expression is not constant, give ERROR emsg.  returns the index
   of the first character past the end of the expression. */

static int
exp_get_abs (emsg, idx, in, val)
     const char *emsg;
     int idx;
     sb *in;
     int *val;
{
  exp_t res;
  idx = exp_parse (idx, in, &res);
  if (res.add_symbol.len || res.sub_symbol.len)
    ERROR ((stderr, emsg));
  *val = res.value;
  return idx;
}


sb label; /* current label parsed from line */
hash_table assign_hash_table;   /* hash table for all assigned variables */
hash_table keyword_hash_table;  /* hash table for keyword */
hash_table vars;  /* hash table for  eq variables */

#define in_comment ';'

#if 0
static void
strip_comments (out)
     sb *out;
{
  char *s = out->ptr;
  int i = 0;
  for (i = 0; i < out->len; i++)
    {
      if (ISCOMMENTCHAR(s[i]))
	{
	  out->len = i;
	  return;
	}
    }
}
#endif

/* push back character ch so that it can be read again. */

static void
unget (ch)
     int ch;
{
  if (ch == '\n')
    {
      sp->linecount--;
    }
  if (sp->pushback_index)
    sp->pushback_index--;
  else
    sb_add_char (&sp->pushback, ch);
}

/* push the sb ptr onto the include stack, with the given name, type and index. */

static
void
include_buf (name, ptr, type, index)
     sb *name;
     sb *ptr;
     include_type type;
     int index;
{
  sp++;
  if (sp - include_stack >= MAX_INCLUDES)
    FATAL ((stderr, "unreasonable nesting.\n"));
  sb_new (&sp->name);
  sb_add_sb (&sp->name, name);
  sp->handle = 0;
  sp->linecount = 1;
  sp->pushback_index = 0;
  sp->type = type;
  sp->index = index;
  sb_new (&sp->pushback);
  sb_add_sb (&sp->pushback, ptr);
}


/* used in ERROR messages, print info on where the include stack is onto file. */
static 
void
include_print_where_line (file)
     FILE *file;
{
  struct include_stack *p = include_stack + 1;

  while (p <= sp)
    {
      fprintf (file, "%s:%d ", sb_name (&p->name), p->linecount - 1);
      p++;
    }
}

/* used in listings, print the line number onto file. */
static void
include_print_line (file)
     FILE *file;
{
  int n;
  struct include_stack *p = include_stack + 1;

  n = fprintf (file, "%4d", p->linecount);
  p++;
  while (p <= sp)
    {
      n += fprintf (file, ".%d", p->linecount);
      p++;
    }
  while (n < 8 * 3)
    {
      fprintf (file, " ");
      n++;
    }
}


/* read a line from the top of the include stack into sb in. */

static int
get_line (in)
     sb *in;
{
  int online = 0;
  int more = 1;

  if (copysource)
    {
      putc (comment_char, outfile);
      if (print_line_number)
	include_print_line (outfile);
    }

  while (1)
    {
      int ch = get ();

      while (ch == '\r')
	ch = get ();

      if (ch == EOF)
	{
	  if (online)
	    {
	      WARNING ((stderr, "End of file not at start of line.\n"));
	      if (copysource)
		putc ('\n', outfile);
	      ch = '\n';
	    }
	  else
	    more = 0;
	  break;
	}

      if (copysource)
	{
	  putc (ch, outfile);
	}

      if (ch == '\n')
	{
	  ch = get ();
	  online = 0;
	  if (ch == '+')
	    {
	      /* continued line */
	      if (copysource)
		{
		  putc (comment_char, outfile);
		  putc ('+', outfile);
		}
	      ch = get ();
	    }
	  else
	    {
	      if (ch != EOF)
		unget (ch);
	      break;
	    }
	}
      else
	{
	  sb_add_char (in, ch);
	}
      online++;
    }

  return more;
}

/* find a label from sb in and put it in out. */

static int
grab_label (in, out)
     sb *in;
     sb *out;
{
  int i = 0;
  sb_reset (out);
  if (ISFIRSTCHAR (in->ptr[i]))
    {
      sb_add_char (out, in->ptr[i]);
      i++;
      while ((ISNEXTCHAR (in->ptr[i]) 
	      || in->ptr[i] == '\\'
	      || in->ptr[i] == '&') 
	     && i < in->len)
	{
	  sb_add_char (out, in->ptr[i]);
	  i++;
	}
    }
  return i;
}

/* find all strange base stuff and turn into decimal. also
   find all the other numbers and convert them from the default radix */

static void
change_base (idx, in, out)
     int idx;
     sb *in;
     sb *out;
{
  char buffer[20];

  while (idx < in->len)
    {
      if (idx < in->len - 1 && in->ptr[idx + 1] == '\'' && ! mri)
	{
	  int base;
	  int value;
	  switch (in->ptr[idx])
	    {
	    case 'b':
	    case 'B':
	      base = 2;
	      break;
	    case 'q':
	    case 'Q':
	      base = 8;
	      break;
	    case 'h':
	    case 'H':
	      base = 16;
	      break;
	    case 'd':
	    case 'D':
	      base = 10;
	      break;
	    default:
	      ERROR ((stderr, "Illegal base character %c.\n", in->ptr[idx]));
	      base = 10;
	      break;
	    }

	  idx = sb_strtol (idx + 2, in, base, &value);
	  sprintf (buffer, "%d", value);
	  sb_add_string (out, buffer);
	}
      else if (ISFIRSTCHAR (in->ptr[idx]))
	{
	  /* copy entire names through quickly */
	  sb_add_char (out, in->ptr[idx]);
	  idx++;
	  while (idx < in->len && ISNEXTCHAR (in->ptr[idx]))
	    {
	      sb_add_char (out, in->ptr[idx]);
	      idx++;
	    }
	}
      else if (isdigit (in->ptr[idx]))
	{
	  int value;
	  /* all numbers must start with a digit, let's chew it and
	     spit out decimal */
	  idx = sb_strtol (idx, in, radix, &value);
	  sprintf (buffer, "%d", value);
	  sb_add_string (out, buffer);

	  /* skip all undigsested letters */
	  while (idx < in->len && ISNEXTCHAR (in->ptr[idx]))
	    {
	      sb_add_char (out, in->ptr[idx]);
	      idx++;
	    }
	}
      else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
	{
	  char tchar = in->ptr[idx];
	  /* copy entire names through quickly */
	  sb_add_char (out, in->ptr[idx]);
	  idx++;
	  while (idx < in->len && in->ptr[idx] != tchar)
	    {
	      sb_add_char (out, in->ptr[idx]);
	      idx++;
	    }
	}
      else
	{
	  /* nothing special, just pass it through */
	  sb_add_char (out, in->ptr[idx]);
	  idx++;
	}
    }

}

/* .end */
static void
do_end (in)
     sb *in;
{
  had_end = 1;
  if (mri)
    fprintf (outfile, "%s\n", sb_name (in));
}

/* .assign */

static void
do_assign (again, idx, in)
     int again;
     int idx;
     sb *in;
{
  /* stick label in symbol table with following value */
  exp_t e;
  sb acc;

  sb_new (&acc);
  idx = exp_parse (idx, in, &e);
  exp_string (&e, &acc);
  hash_add_to_string_table (&assign_hash_table, &label, &acc, again);
  sb_kill (&acc);
}


/* .radix [b|q|d|h] */

static
void
do_radix (ptr)
     sb *ptr;
{
  int idx = sb_skip_white (0, ptr);
  switch (ptr->ptr[idx])
    {
    case 'B':
    case 'b':
      radix = 2;
      break;
    case 'q':
    case 'Q':
      radix = 8;
      break;
    case 'd':
    case 'D':
      radix = 10;
      break;
    case 'h':
    case 'H':
      radix = 16;
      break;
    default:
      ERROR ((stderr, "radix is %c must be one of b, q, d or h", radix));
    }
}


/* Parse off a .b, .w or .l */

static int
get_opsize (idx, in, size)
     int idx;
     sb *in;
     int *size;
{
  *size = 4;
  if (in->ptr[idx] == '.')
    {
      idx++;
    }
  switch (in->ptr[idx])
    {
    case 'b':
    case 'B':
      *size = 1;
      break;
    case 'w':
    case 'W':
      *size = 2;
      break;
    case 'l':
    case 'L':
      *size = 4;
      break;
    case ' ':
    case '\t':
      break;
    default:
      ERROR ((stderr, "size must be one of b, w or l, is %c.\n", in->ptr[idx]));
      break;
    }
  idx++;

  return idx;
}

static 
int eol(idx, line)
     int idx;
     sb *line;
{
  idx = sb_skip_white (idx, line);
  if (idx < line->len 
      && ISCOMMENTCHAR(line->ptr[idx]))
    return 1;
  if (idx >= line->len)
    return 1;
  return 0;
}

/* .data [.b|.w|.l] <data>* 
    or d[bwl] <data>* */

static void
do_data (idx, in, size)
     int idx;
     sb *in;
     int size;
{
  int opsize = 4;
  char *opname = ".yikes!";
  sb acc;
  sb_new (&acc);

  if (!size) 
    {
      idx = get_opsize (idx, in, &opsize);
    }
  else {
    opsize = size;
  }
  switch (opsize)
    {
    case 4:
      opname = ".long";
      break;
    case 2:
      opname = ".short";
      break;
    case 1:
      opname = ".byte";
      break;
    }


  fprintf (outfile, "%s\t", opname);

  idx =   sb_skip_white (idx, in);

  if (alternate 
      && idx < in->len 
      && in->ptr[idx] == '"')
    {
      int i;
      idx = getstring (idx, in, &acc);
      for (i = 0; i < acc.len; i++)
	{
	  if (i)
	    fprintf(outfile,",");
	  fprintf (outfile, "%d", acc.ptr[i]);
	}
    }
  else 
    {
      while (!eol (idx, in))
	{
	  exp_t e;
	  idx = exp_parse (idx, in, &e);
	  exp_string (&e, &acc);
	  sb_add_char (&acc, 0);
	  fprintf (outfile, acc.ptr);
	  if (idx < in->len && in->ptr[idx] == ',')
	    {
	      fprintf (outfile, ",");
	      idx++;
	    }
	}
    }
  sb_kill (&acc);
  sb_print_at (outfile, idx, in);
  fprintf (outfile, "\n");
}

/* .datab [.b|.w|.l] <repeat>,<fill> */

static void
do_datab (idx, in)
     int idx;
     sb *in;
{
  int opsize;
  int repeat;
  int fill;

  idx = get_opsize (idx, in, &opsize);

  idx = exp_get_abs ("datab repeat must be constant.\n", idx, in, &repeat);
  idx = sb_skip_comma (idx, in);
  idx = exp_get_abs ("datab data must be absolute.\n", idx, in, &fill);

  fprintf (outfile, ".fill\t%d,%d,%d\n", repeat, opsize, fill);
}

/* .align <size> */

static void
do_align (idx, in)
     int idx;
     sb *in;
{
  int al;
  idx = exp_get_abs ("align needs absolute expression.\n", idx, in, &al);

  if (al != 1
      && al != 2
      && al != 4)
    WARNING ((stderr, "alignment must be one of 1, 2 or 4.\n"));

  fprintf (outfile, ".align	%d\n", al);
}

/* .res[.b|.w|.l] <size> */

static void
do_res (idx, in, type)
     int idx;
     sb *in;
     int type;
{
  int size = 4;
  int count = 0;

  idx = get_opsize (idx, in, &size);
  while (!eol(idx, in))
    {
      idx = sb_skip_white (idx, in);
      if (in->ptr[idx] == ',')
	idx++;
      idx = exp_get_abs ("res needs absolute expression for fill count.\n", idx, in, &count);

      if (type == 'c' || type == 'z')
	count++;

      fprintf (outfile, ".space	%d\n", count * size);
    }
}


/* .export */

static void
do_export (in)
     sb *in;
{
  fprintf (outfile, ".global	%s\n", sb_name (in));
}

/* .print [list] [nolist] */

static void
do_print (idx, in)
     int idx;
     sb *in;
{
  idx = sb_skip_white (idx, in);
  while (idx < in->len)
    {
      if (strncasecmp (in->ptr + idx, "LIST", 4) == 0)
	{
	  fprintf (outfile, ".list\n");
	  idx += 4;
	}
      else if (strncasecmp (in->ptr + idx, "NOLIST", 6) == 0)
	{
	  fprintf (outfile, ".nolist\n");
	  idx += 6;
	}
      idx++;
    }
}

/* .head */
static void
do_heading (idx, in)
     int idx;
     sb *in;
{
  sb head;
  sb_new (&head);
  idx = getstring (idx, in, &head);
  fprintf (outfile, ".title	\"%s\"\n", sb_name (&head));
  sb_kill (&head);
}

/* .page */

static void
do_page ()
{
  fprintf (outfile, ".eject\n");
}

/* .form [lin=<value>] [col=<value>] */
static void
do_form (idx, in)
     int idx;
     sb *in;
{
  int lines = 60;
  int columns = 132;
  idx = sb_skip_white (idx, in);

  while (idx < in->len)
    {

      if (strncasecmp (in->ptr + idx, "LIN=", 4) == 0)
	{
	  idx += 4;
	  idx = exp_get_abs ("form LIN= needs absolute expresssion.\n", idx, in, &lines);
	}

      if (strncasecmp (in->ptr + idx, "COL=", 4) == 0)
	{
	  idx += 4;
	  idx = exp_get_abs ("form COL= needs absolute expresssion.\n", idx, in, &columns);
	}

      idx++;
    }
  fprintf (outfile, ".psize %d,%d\n", lines, columns);

}


/* Fetch string from the input stream,
   rules:
    'Bxyx<whitespace>  	-> return 'Bxyza
    %<char>		-> return string of decimal value of x
    "<string>"		-> return string
    xyx<whitespace>     -> return xyz
*/
static int
get_any_string (idx, in, out, expand, pretend_quoted)
     int idx;
     sb *in;
     sb *out;
     int expand;
     int pretend_quoted;
{
  sb_reset (out);
  idx = sb_skip_white (idx, in);

  if (idx < in->len)
    {
      if (in->len > 2 && in->ptr[idx+1] == '\'' && ISBASE (in->ptr[idx]))
	{
	  while (!ISSEP (in->ptr[idx]))
	    sb_add_char (out, in->ptr[idx++]);
	}
      else if (in->ptr[idx] == '%'
	       && alternate
	       && expand)
	{
	  int val;
	  char buf[20];
	  /* Turns the next expression into a string */
	  idx = exp_get_abs ("% operator needs absolute expression",
			     idx + 1,
			     in,
			     &val);
	  sprintf(buf, "%d", val);
	  sb_add_string (out, buf);
	}
      else if (in->ptr[idx] == '"'
	       || in->ptr[idx] == '<'
	       || (alternate && in->ptr[idx] == '\''))
	{
	  if (alternate && expand)
	    {
	      /* Keep the quotes */
	      sb_add_char (out,  '\"');
		    
	      idx =  getstring (idx, in, out);
	      sb_add_char (out,  '\"');

	    }
	  else {
	    idx = getstring (idx, in, out);
	  }
	}
      else 
	{
	  while (idx < in->len 
		 && (in->ptr[idx] == '"'
		     || in->ptr[idx] == '\''
		     || pretend_quoted 
		     || !ISSEP (in->ptr[idx])))
	    {
	      if (in->ptr[idx] == '"' 
		  || in->ptr[idx] == '\'')
		{
		  char tchar = in->ptr[idx];
		  sb_add_char (out, in->ptr[idx++]);
		  while (idx < in->len
			 && in->ptr[idx] != tchar)
		    sb_add_char (out, in->ptr[idx++]);		    
		  if (idx == in->len)
		    return idx;	      
		}
	      sb_add_char (out, in->ptr[idx++]);
	    }
	}
    }

  return idx;
}


/* skip along sb in starting at idx, suck off whitespace a ( and more
   whitespace.  return the idx of the next char */

static int
skip_openp (idx, in)
     int idx;
     sb *in;
{
  idx = sb_skip_white (idx, in);
  if (in->ptr[idx] != '(')
    ERROR ((stderr, "misplaced ( .\n"));
  idx = sb_skip_white (idx + 1, in);
  return idx;
}

/* skip along sb in starting at idx, suck off whitespace a ) and more
   whitespace.  return the idx of the next char */

static int
skip_closep (idx, in)
     int idx;
     sb *in;
{
  idx = sb_skip_white (idx, in);
  if (in->ptr[idx] != ')')
    ERROR ((stderr, "misplaced ).\n"));
  idx = sb_skip_white (idx + 1, in);
  return idx;
}

/* .len */

static int
dolen (idx, in, out)
     int idx;
     sb *in;
     sb *out;
{

  sb stringout;
  char buffer[10];

  sb_new (&stringout);
  idx = skip_openp (idx, in);
  idx = get_and_process (idx, in, &stringout);
  idx = skip_closep (idx, in);
  sprintf (buffer, "%d", stringout.len);
  sb_add_string (out, buffer);

  sb_kill (&stringout);
  return idx;
}


/* .instr */

static
int
doinstr (idx, in, out)
     int idx;
     sb *in;
     sb *out;
{
  sb string;
  sb search;
  int i;
  int start;
  int res;
  char buffer[10];

  sb_new (&string);
  sb_new (&search);
  idx = skip_openp (idx, in);
  idx = get_and_process (idx, in, &string);
  idx = sb_skip_comma (idx, in);
  idx = get_and_process (idx, in, &search);
  idx = sb_skip_comma (idx, in);
  if (isdigit (in->ptr[idx]))
    {
      idx = exp_get_abs (".instr needs absolute expresson.\n", idx, in, &start);
    }
  else
    {
      start = 0;
    }
  idx = skip_closep (idx, in);
  res = -1;
  for (i = start; i < string.len; i++)
    {
      if (strncmp (string.ptr + i, search.ptr, search.len) == 0)
	{
	  res = i;
	  break;
	}
    }
  sprintf (buffer, "%d", res);
  sb_add_string (out, buffer);
  sb_kill (&string);
  sb_kill (&search);
  return idx;
}


static int
dosubstr (idx, in, out)
     int idx;
     sb *in;
     sb *out;
{
  sb string;
  int pos;
  int len;
  sb_new (&string);

  idx = skip_openp (idx, in);
  idx = get_and_process (idx, in, &string);
  idx = sb_skip_comma (idx, in);
  idx = exp_get_abs ("need absolute position.\n", idx, in, &pos);
  idx = sb_skip_comma (idx, in);
  idx = exp_get_abs ("need absolute length.\n", idx, in, &len);
  idx = skip_closep (idx, in);


  if (len < 0 || pos < 0 ||
      pos > string.len
      || pos + len > string.len)
    {
      sb_add_string (out, " ");
    }
  else 
    {
      sb_add_char (out, '"');
      while (len > 0)
	{
	  sb_add_char (out, string.ptr[pos++]);
	  len--;
	}
      sb_add_char (out, '"');
    }
  sb_kill(&string);
  return idx;
}

/* scan line, change tokens in the hash table to their replacements */
static void
process_assigns (idx, in, buf)
     int idx;
     sb *in;
     sb *buf;
{
  while (idx < in->len)
    {
      hash_entry *ptr;
      if (in->ptr[idx] == '\\'
	  && in->ptr[idx + 1] == '&')
	{
	  idx = condass_lookup_name (in, idx + 2, buf, 1);
	}
      else if (in->ptr[idx] == '\\'
	       && in->ptr[idx + 1] == '$')
	{
	  idx = condass_lookup_name (in, idx + 2, buf, 0);
	}
      else if (idx + 3 < in->len
	       && in->ptr[idx] == '.'
	       && toupper ((unsigned char) in->ptr[idx + 1]) == 'L'
	       && toupper ((unsigned char) in->ptr[idx + 2]) == 'E'
	       && toupper ((unsigned char) in->ptr[idx + 3]) == 'N')
	idx = dolen (idx + 4, in, buf);
      else if (idx + 6 < in->len
	       && in->ptr[idx] == '.'
	       && toupper ((unsigned char) in->ptr[idx + 1]) == 'I'
	       && toupper ((unsigned char) in->ptr[idx + 2]) == 'N'
	       && toupper ((unsigned char) in->ptr[idx + 3]) == 'S'
	       && toupper ((unsigned char) in->ptr[idx + 4]) == 'T'
	       && toupper ((unsigned char) in->ptr[idx + 5]) == 'R')
	idx = doinstr (idx + 6, in, buf);
      else if (idx + 7 < in->len
	       && in->ptr[idx] == '.'
	       && toupper ((unsigned char) in->ptr[idx + 1]) == 'S'
	       && toupper ((unsigned char) in->ptr[idx + 2]) == 'U'
	       && toupper ((unsigned char) in->ptr[idx + 3]) == 'B'
	       && toupper ((unsigned char) in->ptr[idx + 4]) == 'S'
	       && toupper ((unsigned char) in->ptr[idx + 5]) == 'T'
	       && toupper ((unsigned char) in->ptr[idx + 6]) == 'R')
	idx = dosubstr (idx + 7, in, buf);
      else if (ISFIRSTCHAR (in->ptr[idx]))
	{
	  /* may be a simple name subsitution, see if we have a word */
	  sb acc;
	  int cur = idx + 1;
	  while (cur < in->len
		 && (ISNEXTCHAR (in->ptr[cur])))
	    cur++;

	  sb_new (&acc);
	  sb_add_buffer (&acc, in->ptr + idx, cur - idx);
	  ptr = hash_lookup (&assign_hash_table, &acc);
	  if (ptr)
	    {
	      /* Found a definition for it */
	      sb_add_sb (buf, &ptr->value.s);
	    }
	  else
	    {
	      /* No definition, just copy the word */
	      sb_add_sb (buf, &acc);
	    }
	  sb_kill (&acc);
	  idx = cur;
	}
      else
	{
	  sb_add_char (buf, in->ptr[idx++]);
	}
    }
}

static int
get_and_process (idx, in, out)
     int idx;
     sb *in;
     sb *out;
{
  sb t;
  sb_new (&t);
  idx = get_any_string (idx, in, &t, 1, 0);
  process_assigns (0, &t, out);
  sb_kill (&t);
  return idx;
}

static
void
process_file ()
{
  sb line;
  sb t1, t2;
  sb acc;
  sb label_in;
  int more;

  sb_new (&line);
  sb_new (&t1);
  sb_new (&t2);
  sb_new(&acc);
  sb_new (&label_in);
  sb_reset (&line);
  more = get_line (&line);
  while (more)
    {
      /* Find any label and pseudo op that we're intested in */
      int l;
      if (line.len == 0)
	{
	  if (condass_on ())
	    fprintf (outfile, "\n");
	}
      else if (mri
	       && (line.ptr[0] == '*'
		   || line.ptr[0] == '!'))
	{
	  /* MRI line comment.  */
	  fprintf (outfile, sb_name (&line));
	}
      else
	{
	  l = grab_label (&line, &label_in);
	  sb_reset (&label);	  	  
	  if (label_in.len)
	    {
	      /* Munge any label */

	      
	      process_assigns (0, &label_in, &label);
	    }

	  if (line.ptr[l] == ':')
	    l++;
	  while (ISWHITE (line.ptr[l]) && l < line.len)
	    l++;

	  if (l < line.len)
	    {
	      if (process_pseudo_op (l, &line, &acc))
		{



		}
	      else if (condass_on ())
		{
		  if (macro_op (l, &line))
		    {


		    }
		  else
		    {
		      {
			if (label.len)
			  {
			    fprintf (outfile, "%s:\t", sb_name (&label));
			  }
			else
			  fprintf (outfile, "\t");
			sb_reset(&t1);
			process_assigns (l, &line, &t1);
			sb_reset (&t2);
			change_base (0, &t1, &t2);
			fprintf (outfile, "%s\n", sb_name (&t2));
		      }
		    }
		}
	    }
	  else {
	    /* Only a label on this line */
	    if (label.len && condass_on())
	      {
		fprintf (outfile, "%s:\n", sb_name (&label));
	      }
	  }
	}

      if (had_end)
	break;
      sb_reset (&line);
      more = get_line (&line);
    }

  if (!had_end && !mri)
    WARNING ((stderr, "END missing from end of file.\n"));
}





static void
free_old_entry (ptr)
     hash_entry *ptr;
{
  if (ptr)
    {
      if (ptr->type == hash_string)
	sb_kill(&ptr->value.s);
    }
}

/* name: .ASSIGNA <value> */

static void
do_assigna (idx, in)
     int idx;
     sb *in;
{
  sb tmp;
  int val;
  sb_new (&tmp);

  process_assigns (idx, in, &tmp);
  idx = exp_get_abs (".ASSIGNA needs constant expression argument.\n", 0, &tmp, &val);

  if (!label.len)
    {
      ERROR ((stderr, ".ASSIGNA without label.\n"));
    }
  else
    {
      hash_entry *ptr = hash_create (&vars, &label);
      free_old_entry (ptr);
      ptr->type = hash_integer;
      ptr->value.i = val;
    }
  sb_kill (&tmp);
}

/* name: .ASSIGNC <string> */

static void
do_assignc (idx, in)
     int idx;
     sb *in;
{
  sb acc;
  sb_new (&acc);
  idx = getstring (idx, in, &acc);

  if (!label.len)
    {
      ERROR ((stderr, ".ASSIGNS without label.\n"));
    }
  else
    {
      hash_entry *ptr = hash_create (&vars, &label);
      free_old_entry (ptr);
      ptr->type = hash_string;
      sb_new (&ptr->value.s);
      sb_add_sb (&ptr->value.s, &acc);
    }
  sb_kill (&acc);
}


/* name: .REG (reg) */

static void
do_reg (idx, in)
     int idx;
     sb *in;
{
  /* remove reg stuff from inside parens */
  sb what;
  if (!mri)
    idx = skip_openp (idx, in);
  else
    idx = sb_skip_white (idx, in);
  sb_new (&what);
  while (idx < in->len
	 && (mri
	     ? ! eol (idx, in)
	     : in->ptr[idx] != ')'))
    {
      sb_add_char (&what, in->ptr[idx]);
      idx++;
    }
  hash_add_to_string_table (&assign_hash_table, &label, &what, 1);
  sb_kill (&what);
}


static int
condass_lookup_name (inbuf, idx, out, warn)
     sb *inbuf;
     int idx;
     sb *out;
     int warn;
{
  hash_entry *ptr;
  sb condass_acc;
  sb_new (&condass_acc);

  while (idx < inbuf->len
	 && ISNEXTCHAR (inbuf->ptr[idx]))
    {
      sb_add_char (&condass_acc, inbuf->ptr[idx++]);
    }

  if (inbuf->ptr[idx] == '\'')
    idx++;
  ptr = hash_lookup (&vars, &condass_acc);


  if (!ptr)
    {
      if (warn) 
	{
	  WARNING ((stderr, "Can't find preprocessor variable %s.\n", sb_name (&condass_acc)));
	}
      else 
	{
	  sb_add_string (out, "0");
	}
    }
  else
    {
      if (ptr->type == hash_integer)
	{
	  char buffer[30];
	  sprintf (buffer, "%d", ptr->value.i);
	  sb_add_string (out, buffer);
	}
      else
	{
	  sb_add_sb (out, &ptr->value.s);
	}
    }
  sb_kill (&condass_acc);
  return idx;
}

#define EQ 1
#define NE 2
#define GE 3
#define LT 4
#define LE 5
#define GT 6
#define NEVER 7

static int
whatcond (idx, in, val)
     int idx;
     sb *in;
     int *val;
{
  int cond;

  idx = sb_skip_white (idx, in);
  cond = NEVER;
  if (idx + 1 < in->len)
    {
      char *p;
      char a, b;

      p = in->ptr + idx;
      a = toupper ((unsigned char) p[0]);
      b = toupper ((unsigned char) p[1]);
      if (a == 'E' && b == 'Q')
	cond = EQ;
      else if (a == 'N' && b == 'E')
	cond = NE;
      else if (a == 'L' && b == 'T')
	cond = LT;
      else if (a == 'L' && b == 'E')
	cond = LE;
      else if (a == 'G' && b == 'T')
	cond = GT;
      else if (a == 'G' && b == 'E')
	cond = GE;
    }
  if (cond == NEVER)
    {
      ERROR ((stderr, "Comparison operator must be one of EQ, NE, LT, LE, GT or GE.\n"));
      cond = NEVER;
    }
  idx = sb_skip_white (idx + 2, in);
  *val = cond;
  return idx;
}

static int
istrue (idx, in)
     int idx;
     sb *in;
{
  int res;
  sb acc_a;
  sb cond;
  sb acc_b;
  sb_new (&acc_a);
  sb_new (&cond);
  sb_new (&acc_b);
  idx = sb_skip_white (idx, in);

  if (in->ptr[idx] == '"')
    {
      int cond;
      int same;
      /* This is a string comparision */
      idx = getstring (idx, in, &acc_a);
      idx = whatcond (idx, in, &cond);
      idx = getstring (idx, in, &acc_b);
      same = acc_a.len == acc_b.len && (strncmp (acc_a.ptr, acc_b.ptr, acc_a.len) == 0);

      if (cond != EQ && cond != NE)
	{
	  ERROR ((stderr, "Comparison operator for strings must be EQ or NE\n"));
	  res = 0;
	}
      else
	res = (cond != EQ) ^ same;
    }
  else
    /* This is a numeric expression */
    {
      int vala;
      int valb;
      int cond;
      idx = exp_get_abs ("Conditional operator must have absolute operands.\n", idx, in, &vala);
      idx = whatcond (idx, in, &cond);
      idx = sb_skip_white (idx, in);
      if (in->ptr[idx] == '"')
	{
	  WARNING ((stderr, "String compared against expression.\n"));
	  res = 0;
	}
      else
	{
	  idx = exp_get_abs ("Conditional operator must have absolute operands.\n", idx, in, &valb);
	  switch (cond)
	    {
	    default:
	      res = 42;
	      break;
	    case EQ:
	      res = vala == valb;
	      break;
	    case NE:
	      res = vala != valb;
	      break;
	    case LT:
	      res = vala < valb;
	      break;
	    case LE:
	      res = vala <= valb;
	      break;
	    case GT:
	      res = vala > valb;
	      break;
	    case GE:
	      res = vala >= valb;
	      break;
	    case NEVER:
	      res = 0;
	      break;
	    }
	}
    }

  sb_kill (&acc_a);
  sb_kill (&cond);
  sb_kill (&acc_b);
  return res;
}

/* .AIF */
static void
do_aif (idx, in)
     int idx;
     sb *in;
{
  if (ifi >= IFNESTING)
    {
      FATAL ((stderr, "AIF nesting unreasonable.\n"));
    }
  ifi++;
  ifstack[ifi].on = ifstack[ifi-1].on ? istrue (idx, in) : 0;
  ifstack[ifi].hadelse = 0;
}


/* .AELSE */
static void
do_aelse ()
{
  ifstack[ifi].on = ifstack[ifi-1].on ? !ifstack[ifi].on : 0;
  if (ifstack[ifi].hadelse)
    {
      ERROR ((stderr, "Multiple AELSEs in AIF.\n"));
    }
  ifstack[ifi].hadelse = 1;
}


/* .AENDI */
static void
do_aendi ()
{
  if (ifi != 0)
    {
      ifi--;
    }
  else
    {
      ERROR ((stderr, "AENDI without AIF.\n"));
    }
}

static int
condass_on ()
{
  return ifstack[ifi].on;
}

/* MRI IFEQ, IFNE, IFLT, IFLE, IFGE, IFGT.  */

static void
do_if (idx, in, cond)
     int idx;
     sb *in;
     int cond;
{
  int val;
  int res;

  if (ifi >= IFNESTING)
    {
      FATAL ((stderr, "IF nesting unreasonable.\n"));
    }

  idx = exp_get_abs ("Conditional operator must have absolute operands.\n",
		     idx, in, &val);
  switch (cond)
    {
    default:
    case EQ: res = val == 0; break;
    case NE: res = val != 0; break;
    case LT: res = val <  0; break;
    case LE: res = val <= 0; break;
    case GE: res = val >= 0; break;
    case GT: res = val >  0; break;
    }

  ifi++;
  ifstack[ifi].on = ifstack[ifi-1].on ? res: 0;
  ifstack[ifi].hadelse = 0;
}

/* Get a string for the MRI IFC or IFNC pseudo-ops.  */

static int
get_mri_string (idx, in, val, terminator)
     int idx;
     sb *in;
     sb *val;
     int terminator;
{
  idx = sb_skip_white (idx, in);

  if (idx < in->len
      && in->ptr[idx] == '\'')
    {
      sb_add_char (val, '\'');
      for (++idx; idx < in->len; ++idx)
	{
	  sb_add_char (val, in->ptr[idx]);
	  if (in->ptr[idx] == '\'')
	    {
	      ++idx;
	      if (idx >= in->len
		  || in->ptr[idx] != '\'')
		break;
	    }
	}
      idx = sb_skip_white (idx, in);
    }
  else
    {
      int i;

      while (idx < in->len
	     && in->ptr[idx] != terminator)
	{
	  sb_add_char (val, in->ptr[idx]);
	  ++idx;
	}
      i = val->len - 1;
      while (i >= 0 && ISWHITE (val->ptr[i]))
	--i;
      val->len = i + 1;
    }

  return idx;
}

/* MRI IFC, IFNC.  */

static void
do_ifc (idx, in, ifnc)
     int idx;
     sb *in;
     int ifnc;
{
  sb first;
  sb second;
  int res;

  if (ifi >= IFNESTING)
    {
      FATAL ((stderr, "IF nesting unreasonable.\n"));
    }

  sb_new (&first);
  sb_new (&second);

  idx = get_mri_string (idx, in, &first, ',');

  if (idx >= in->len || in->ptr[idx] != ',')
    {
      ERROR ((stderr, "Bad format for IF or IFNC.\n"));
      return;
    }

  idx = get_mri_string (idx + 1, in, &second, ';');

  res = (first.len == second.len
	 && strncmp (first.ptr, second.ptr, first.len) == 0);
  res ^= ifnc;

  ifi++;
  ifstack[ifi].on = ifstack[ifi-1].on ? res : 0;
  ifstack[ifi].hadelse = 0;
}

/* .ENDR */
static void
do_aendr ()
{
  if (!mri)
    ERROR ((stderr, "AENDR without a AREPEAT.\n"));
  else
    ERROR ((stderr, "ENDR without a REPT.\n"));
}

/* .AWHILE */

static
void
do_awhile (idx, in)
     int idx;
     sb *in;
{
  int line = linecount ();
  sb exp;
  sb sub;
  int doit;

  sb_new (&sub);
  sb_new (&exp);

  process_assigns (idx, in, &exp);
  doit = istrue (0, &exp);

  if (! buffer_and_nest ("AWHILE", "AENDW", &sub, get_line))
    FATAL ((stderr, "AWHILE without a AENDW at %d.\n", line - 1));

  /* Turn
     	.AWHILE exp
	     foo
	.AENDW
     into
        foo
	.AWHILE exp
	foo
	.ENDW
   */

  if (doit)
    {
      int index = include_next_index ();

      sb copy;
      sb_new (&copy);
      sb_add_sb (&copy, &sub);
      sb_add_sb (&copy, in);
      sb_add_string (&copy, "\n");
      sb_add_sb (&copy, &sub);
      sb_add_string (&copy, "\t.AENDW\n");
      /* Push another WHILE */
      include_buf (&exp, &copy, include_while, index);
      sb_kill (&copy);
    }
  sb_kill (&exp);
  sb_kill (&sub);
}


/* .AENDW */

static void
do_aendw ()
{
  ERROR ((stderr, "AENDW without a AENDW.\n"));
}


/* .EXITM
   
   Pop things off the include stack until the type and index changes */

static void
do_exitm ()
{
  include_type type = sp->type;
  if (type == include_repeat
      || type == include_while
      || type == include_macro)
    {
      int index = sp->index;
      include_pop ();
      while (sp->index == index
	     && sp->type == type)
	{
	  include_pop ();
	}
    }
}

/* .AREPEAT */

static void
do_arepeat (idx, in)
     int idx;
     sb *in;
{
  int line = linecount ();
  sb exp;			/* buffer with expression in it */
  sb copy;			/* expanded repeat block */
  sb sub;			/* contents of AREPEAT */
  int rc;
  int ret;
  char buffer[30];

  sb_new (&exp);
  sb_new (&copy);
  sb_new (&sub);
  process_assigns (idx, in, &exp);
  idx = exp_get_abs ("AREPEAT must have absolute operand.\n", 0, &exp, &rc);
  if (!mri)
    ret = buffer_and_nest ("AREPEAT", "AENDR", &sub, get_line);
  else
    ret = buffer_and_nest ("REPT", "ENDR", &sub, get_line);
  if (! ret)
    FATAL ((stderr, "AREPEAT without a AENDR at %d.\n", line - 1));
  if (rc > 0)
    {
      /* Push back the text following the repeat, and another repeat block
	 so
	 .AREPEAT 20
	 foo
	 .AENDR
	 gets turned into
	 foo
	 .AREPEAT 19
	 foo
	 .AENDR
	 */
      int index = include_next_index ();
      sb_add_sb (&copy, &sub);
      if (rc > 1)
	{
	  if (!mri)
	    sprintf (buffer, "\t.AREPEAT	%d\n", rc - 1);
	  else
	    sprintf (buffer, "\tREPT	%d\n", rc - 1);
	  sb_add_string (&copy, buffer);
	  sb_add_sb (&copy, &sub);
	  if (!mri)
	    sb_add_string (&copy, "	.AENDR\n");
	  else
	    sb_add_string (&copy, "	ENDR\n");
	}

      include_buf (&exp, &copy, include_repeat, index);
    }
  sb_kill (&exp);
  sb_kill (&sub);
  sb_kill (&copy);
}

/* .ENDM */

static void
do_endm ()
{
  ERROR ((stderr, ".ENDM without a matching .MACRO.\n"));
}

/* MRI IRP pseudo-op.  */

static void
do_irp (idx, in, irpc)
     int idx;
     sb *in;
     int irpc;
{
  const char *err;
  sb out;

  sb_new (&out);

  err = expand_irp (irpc, idx, in, &out, get_line, comment_char);
  if (err != NULL)
    ERROR ((stderr, "%s\n", err));

  fprintf (outfile, "%s", sb_terminate (&out));

  sb_kill (&out);
}

/* MACRO PROCESSING */

/* Parse off LOCAL n1, n2,... Invent a label name for it */
static
void 
do_local (idx, line)
     int idx;
     sb *line;
{
  ERROR ((stderr, "LOCAL outside of MACRO"));
}

static void
do_macro (idx, in)
     int idx;
     sb *in;
{
  const char *err;
  int line = linecount ();

  err = define_macro (idx, in, &label, get_line);
  if (err != NULL)
    ERROR ((stderr, "macro at line %d: %s\n", line - 1, err));
}

static int
macro_op (idx, in)
     int idx;
     sb *in;
{
  const char *err;
  sb out;
  sb name;

  if (! macro_defined)
    return 0;

  sb_terminate (in);
  if (! check_macro (in->ptr + idx, &out, comment_char, &err))
    return 0;

  if (err != NULL)
    ERROR ((stderr, "%s\n", err));

  sb_new (&name);
  sb_add_string (&name, "macro expansion");

  include_buf (&name, &out, include_macro, include_next_index ());

  sb_kill (&name);
  sb_kill (&out);

  return 1;
}

/* STRING HANDLING */

static int
getstring (idx, in, acc)
     int idx;
     sb *in;
     sb *acc;
{
  idx = sb_skip_white (idx, in);

  while (idx < in->len
	 && (in->ptr[idx] == '"' 
	     || in->ptr[idx] == '<' 
	     || (in->ptr[idx] == '\'' && alternate)))
    {
      if (in->ptr[idx] == '<')
	{
	  if (alternate || mri)
	    {
	      int nest = 0;
	      idx++;
	      while ((in->ptr[idx] != '>' || nest)
		     && idx < in->len)
		{
		  if (in->ptr[idx] == '!')
		    {
		      idx++  ;
		      sb_add_char (acc, in->ptr[idx++]);
		    }
		  else {
		    if (in->ptr[idx] == '>')
		      nest--;
		    if (in->ptr[idx] == '<')
		      nest++;
		    sb_add_char (acc, in->ptr[idx++]);
		  }
		}
	      idx++;
	    }
	  else {
	    int code;
	    idx++;
	    idx = exp_get_abs ("Character code in string must be absolute expression.\n",
			       idx, in, &code);
	    sb_add_char (acc, code);

	    if (in->ptr[idx] != '>')
	      ERROR ((stderr, "Missing > for character code.\n"));
	    idx++;
	  }
	}
      else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
	{
	  char tchar = in->ptr[idx];
	  idx++;
	  while (idx < in->len)
	    {
	      if (alternate && in->ptr[idx] == '!')
		{
		  idx++  ;
		  sb_add_char (acc, in->ptr[idx++]);
		}
	      else {
		if (in->ptr[idx] == tchar)
		  {
		    idx++;
		    if (idx >= in->len || in->ptr[idx] != tchar)
		      break;
		  }
		sb_add_char (acc, in->ptr[idx]);
		idx++;
	      }
	    }
	}
    }
  
  return idx;
}

/* .SDATA[C|Z] <string> */

static
void
do_sdata (idx, in, type)
     int idx;
     sb *in;
     int type;
{
  int nc = 0;
  int pidx = -1;
  sb acc;
  sb_new (&acc);
  fprintf (outfile, ".byte\t");

  while (!eol (idx, in))
    {
      int i;
      sb_reset (&acc);
      idx = sb_skip_white (idx, in);
      while (!eol (idx, in))
	{
	  pidx = idx = get_any_string (idx, in, &acc, 0, 1);
	  if (type == 'c')
	    {
	      if (acc.len > 255)
		{
		  ERROR ((stderr, "string for SDATAC longer than 255 characters (%d).\n", acc.len));
		}
	      fprintf (outfile, "%d", acc.len);
	      nc = 1;
	    }

	  for (i = 0; i < acc.len; i++)
	    {
	      if (nc)
		{
		  fprintf (outfile, ",");
		}
	      fprintf (outfile, "%d", acc.ptr[i]);
	      nc = 1;
	    }

	  if (type == 'z')
	    {
	      if (nc)
		fprintf (outfile, ",");
	      fprintf (outfile, "0");
	    }
	  idx = sb_skip_comma (idx, in);
	  if (idx == pidx) break;
	}
      if (!alternate && in->ptr[idx] != ',' && idx != in->len)
	{
	  fprintf (outfile, "\n");
	  ERROR ((stderr, "illegal character in SDATA line (0x%x).\n", in->ptr[idx]));
	  break;
	}
      idx++;
    }
  sb_kill (&acc);
  fprintf (outfile, "\n");
}

/* .SDATAB <count> <string> */

static void
do_sdatab (idx, in)
     int idx;
     sb *in;
{
  int repeat;
  int i;
  sb acc;
  sb_new (&acc);

  idx = exp_get_abs ("Must have absolute SDATAB repeat count.\n", idx, in, &repeat);
  if (repeat <= 0)
    {
      ERROR ((stderr, "Must have positive SDATAB repeat count (%d).\n", repeat));
      repeat = 1;
    }

  idx = sb_skip_comma (idx, in);
  idx = getstring (idx, in, &acc);

  for (i = 0; i < repeat; i++)
    {
      if (i)
	fprintf (outfile, "\t");
      fprintf (outfile, ".byte\t");
      sb_print (outfile, &acc);
      fprintf (outfile, "\n");
    }
  sb_kill (&acc);

}

static int
new_file (name)
     const char *name;
{
  FILE *newone = fopen (name, "r");
  if (!newone)
    return 0;

  if (isp == MAX_INCLUDES)
    FATAL ((stderr, "Unreasonable include depth (%ld).\n", (long) isp));

  sp++;
  sp->handle = newone;

  sb_new (&sp->name);
  sb_add_string (&sp->name, name);

  sp->linecount = 1;
  sp->pushback_index = 0;
  sp->type = include_file;
  sp->index = 0;
  sb_new (&sp->pushback);
  return 1;
}

static void
do_include (idx, in)
     int idx;
     sb *in;
{
  sb t;
  sb cat;
  include_path *includes;

  sb_new (&t);
  sb_new (&cat);

  if (! mri)
    idx = getstring (idx, in, &t);
  else
    {
      idx = sb_skip_white (idx, in);
      while (idx < in->len && ! ISWHITE (in->ptr[idx]))
	{
	  sb_add_char (&t, in->ptr[idx]);
	  ++idx;
	}
    }

  for (includes = paths_head; includes; includes = includes->next)
    {
      sb_reset (&cat);
      sb_add_sb (&cat, &includes->path);
      sb_add_char (&cat, '/');
      sb_add_sb (&cat, &t);
      if (new_file (sb_name (&cat)))
	{
	  break;
	}
    }
  if (!includes)
    {
      if (! new_file (sb_name (&t)))
	FATAL ((stderr, "Can't open include file `%s'.\n", sb_name (&t)));
    }
  sb_kill (&cat);
  sb_kill (&t);
}

static void
include_pop ()
{
  if (sp != include_stack)
    {
      if (sp->handle)
	fclose (sp->handle);
      sp--;
    }
}

/* Get the next character from the include stack.  If there's anything
   in the pushback buffer, take that first.  If we're at eof, pop from
   the stack and try again.  Keep the linecount up to date. */

static int
get ()
{
  int r;

  if (sp->pushback.len != sp->pushback_index)
    {
      r = (char) (sp->pushback.ptr[sp->pushback_index++]);
      /* When they've all gone, reset the pointer */
      if (sp->pushback_index == sp->pushback.len)
	{
	  sp->pushback.len = 0;
	  sp->pushback_index = 0;
	}
    }
  else if (sp->handle)
    {
      r = getc (sp->handle);
    }
  else
    r = EOF;

  if (r == EOF && isp)
    {
      include_pop ();
      r = get ();
      while (r == EOF && isp)
	{
	  include_pop ();
	  r = get ();
	}
      return r;
    }
  if (r == '\n')
    {
      sp->linecount++;
    }

  return r;
}

static int
linecount ()
{
  return sp->linecount;
}

static int
include_next_index ()
{
  static int index;
  if (!unreasonable
      && index > MAX_REASONABLE)
    FATAL ((stderr, "Unreasonable expansion (-u turns off check).\n"));
  return ++index;
}


/* Initialize the chartype vector. */

static void
chartype_init ()
{
  int x;
  for (x = 0; x < 256; x++)
    {
      if (isalpha (x) || x == '_' || x == '$')
	chartype[x] |= FIRSTBIT;

      if (mri && x == '.')
	chartype[x] |= FIRSTBIT;

      if (isdigit (x) || isalpha (x) || x == '_' || x == '$')
	chartype[x] |= NEXTBIT;

      if (x == ' ' || x == '\t' || x == ',' || x == '"' || x == ';'
	  || x == '"' || x == '<' || x == '>' || x == ')' || x == '(')
	chartype[x] |= SEPBIT;

      if (x == 'b' || x == 'B'
	  || x == 'q' || x == 'Q'
	  || x == 'h' || x == 'H'
	  || x == 'd' || x == 'D')
	chartype [x] |= BASEBIT;
	  
      if (x == ' ' || x == '\t')
	chartype[x] |= WHITEBIT;

      if (x == comment_char)
	chartype[x] |= COMMENTBIT;
    }
}



/* What to do with all the keywords */
#define PROCESS 	0x1000  /* Run substitution over the line */
#define LAB		0x2000  /* Spit out the label */

#define K_EQU 		(PROCESS|1)
#define K_ASSIGN 	(PROCESS|2)
#define K_REG 		(PROCESS|3)
#define K_ORG 		(PROCESS|4)
#define K_RADIX 	(PROCESS|5)
#define K_DATA 		(LAB|PROCESS|6)
#define K_DATAB 	(LAB|PROCESS|7)
#define K_SDATA 	(LAB|PROCESS|8)
#define K_SDATAB 	(LAB|PROCESS|9)
#define K_SDATAC 	(LAB|PROCESS|10)
#define K_SDATAZ	(LAB|PROCESS|11)
#define K_RES 		(LAB|PROCESS|12)
#define K_SRES 		(LAB|PROCESS|13)
#define K_SRESC 	(LAB|PROCESS|14)
#define K_SRESZ 	(LAB|PROCESS|15)
#define K_EXPORT 	(LAB|PROCESS|16)
#define K_GLOBAL 	(LAB|PROCESS|17)
#define K_PRINT 	(LAB|PROCESS|19)
#define K_FORM 		(LAB|PROCESS|20)
#define K_HEADING	(LAB|PROCESS|21)
#define K_PAGE		(LAB|PROCESS|22)
#define K_IMPORT	(LAB|PROCESS|23)
#define K_PROGRAM	(LAB|PROCESS|24)
#define K_END		(PROCESS|25)
#define K_INCLUDE	(PROCESS|26)
#define K_IGNORED	(PROCESS|27)
#define K_ASSIGNA	(PROCESS|28)
#define K_ASSIGNC	(29)
#define K_AIF		(PROCESS|30)
#define K_AELSE		(PROCESS|31)
#define K_AENDI		(PROCESS|32)
#define K_AREPEAT	(PROCESS|33)
#define K_AENDR		(PROCESS|34)
#define K_AWHILE	(35)
#define K_AENDW		(PROCESS|36)
#define K_EXITM		(37)
#define K_MACRO		(PROCESS|38)
#define K_ENDM		(39)
#define K_ALIGN		(PROCESS|LAB|40)
#define K_ALTERNATE     (41)
#define K_DB		(LAB|PROCESS|42)
#define K_DW		(LAB|PROCESS|43)
#define K_DL		(LAB|PROCESS|44)
#define K_LOCAL		(45)
#define K_IFEQ		(PROCESS|46)
#define K_IFNE		(PROCESS|47)
#define K_IFLT		(PROCESS|48)
#define K_IFLE		(PROCESS|49)
#define K_IFGE		(PROCESS|50)
#define K_IFGT		(PROCESS|51)
#define K_IFC		(PROCESS|52)
#define K_IFNC		(PROCESS|53)
#define K_IRP		(PROCESS|54)
#define K_IRPC		(PROCESS|55)


struct keyword
{
  char *name;
  int code;
  int extra;
};

static struct keyword kinfo[] =
{
  { "EQU", K_EQU, 0 },
  { "ALTERNATE", K_ALTERNATE, 0 },
  { "ASSIGN", K_ASSIGN, 0 },
  { "REG", K_REG, 0 },
  { "ORG", K_ORG, 0 },
  { "RADIX", K_RADIX, 0 },
  { "DATA", K_DATA, 0 },
  { "DB", K_DB, 0 },
  { "DW", K_DW, 0 },
  { "DL", K_DL, 0 },
  { "DATAB", K_DATAB, 0 },
  { "SDATA", K_SDATA, 0 },
  { "SDATAB", K_SDATAB, 0 },
  { "SDATAZ", K_SDATAZ, 0 },
  { "SDATAC", K_SDATAC, 0 },
  { "RES", K_RES, 0 },
  { "SRES", K_SRES, 0 },
  { "SRESC", K_SRESC, 0 },
  { "SRESZ", K_SRESZ, 0 },
  { "EXPORT", K_EXPORT, 0 },
  { "GLOBAL", K_GLOBAL, 0 },
  { "PRINT", K_PRINT, 0 },
  { "FORM", K_FORM, 0 },
  { "HEADING", K_HEADING, 0 },
  { "PAGE", K_PAGE, 0 },
  { "PROGRAM", K_IGNORED, 0 },
  { "END", K_END, 0 },
  { "INCLUDE", K_INCLUDE, 0 },
  { "ASSIGNA", K_ASSIGNA, 0 },
  { "ASSIGNC", K_ASSIGNC, 0 },
  { "AIF", K_AIF, 0 },
  { "AELSE", K_AELSE, 0 },
  { "AENDI", K_AENDI, 0 },
  { "AREPEAT", K_AREPEAT, 0 },
  { "AENDR", K_AENDR, 0 },
  { "EXITM", K_EXITM, 0 },
  { "MACRO", K_MACRO, 0 },
  { "ENDM", K_ENDM, 0 },
  { "AWHILE", K_AWHILE, 0 },
  { "ALIGN", K_ALIGN, 0 },
  { "AENDW", K_AENDW, 0 },
  { "ALTERNATE", K_ALTERNATE, 0 },
  { "LOCAL", K_LOCAL, 0 },
  { NULL, 0, 0 }
};

/* Although the conditional operators are handled by gas, we need to
   handle them here as well, in case they are used in a recursive
   macro to end the recursion.  */

static struct keyword mrikinfo[] =
{
  { "IFEQ", K_IFEQ, 0 },
  { "IFNE", K_IFNE, 0 },
  { "IFLT", K_IFLT, 0 },
  { "IFLE", K_IFLE, 0 },
  { "IFGE", K_IFGE, 0 },
  { "IFGT", K_IFGT, 0 },
  { "IFC", K_IFC, 0 },
  { "IFNC", K_IFNC, 0 },
  { "ELSEC", K_AELSE, 0 },
  { "ENDC", K_AENDI, 0 },
  { "MEXIT", K_EXITM, 0 },
  { "REPT", K_AREPEAT, 0 },
  { "IRP", K_IRP, 0 },
  { "IRPC", K_IRPC, 0 },
  { "ENDR", K_AENDR, 0 },
  { NULL, 0, 0 }
};

/* Look for a pseudo op on the line. If one's there then call
   its handler. */

static int
process_pseudo_op (idx, line, acc)
     int idx;
     sb *line;
     sb *acc;
{
  int oidx = idx;

  if (line->ptr[idx] == '.' || alternate || mri)
    {
      /* Scan forward and find pseudo name */
      char *in;
      hash_entry *ptr;

      char *s;
      char *e;
      if (line->ptr[idx] == '.')
	idx++;
      in = line->ptr + idx;
      s = in;
      e = s;
      sb_reset (acc);

      while (idx < line->len && *e && ISFIRSTCHAR (*e))
	{
	  sb_add_char (acc, *e);
	  e++;
	  idx++;
	}

      ptr = hash_lookup (&keyword_hash_table, acc);

      if (!ptr)
	{
#if 0
	  /* This one causes lots of pain when trying to preprocess
	     ordinary code */
	  WARNING ((stderr, "Unrecognised pseudo op `%s'.\n", sb_name (acc)));
#endif
	  return 0;
	}
      if (ptr->value.i & LAB)
	{			/* output the label */
	  if (label.len)
	    {
	      fprintf (outfile, "%s:\t", sb_name (&label));
	    }
	  else
	    fprintf (outfile, "\t");
	}

      if (mri && ptr->value.i == K_END)
	{
	  sb t;

	  sb_new (&t);
	  sb_add_buffer (&t, line->ptr + oidx, idx - oidx);
	  fprintf (outfile, "\t%s", sb_name (&t));
	  sb_kill (&t);
	}

      if (ptr->value.i & PROCESS)
	{
	  /* Polish the rest of the line before handling the pseudo op */
#if 0
	  strip_comments(line);
#endif
	  sb_reset (acc);
	  process_assigns (idx, line, acc);
	  sb_reset(line);
	  change_base (0, acc, line);
	  idx = 0;
	}
      if (!condass_on ())
	{
	  switch (ptr->value.i)
	    {
	    case K_AIF:
	      do_aif (idx, line);
	      break;
	    case K_AELSE:
	      do_aelse ();
	      break;
	    case K_AENDI:
	      do_aendi ();
	      break;
	    }
	  return 1;
	}
      else
	{
	  switch (ptr->value.i)
	    {
	    case K_ALTERNATE:
	      alternate = 1;
	      macro_init (1, mri, 0, exp_get_abs);
	      return 1;
	    case K_AELSE:
	      do_aelse ();
	      return 1;
	    case K_AENDI:
	      do_aendi ();
	      return 1;
	    case K_ORG:
	      ERROR ((stderr, "ORG command not allowed.\n"));
	      break;
	    case K_RADIX:
	      do_radix (line);
	      return 1;
	    case K_DB:
	      do_data (idx, line, 1);
	      return 1;
	    case K_DW:
	      do_data (idx, line, 2);
	      return 1;
	    case K_DL:
	      do_data (idx, line, 4);
	      return 1;
	    case K_DATA:
	      do_data (idx, line, 0);
	      return 1;
	    case K_DATAB:
	      do_datab (idx, line);
	      return 1;
	    case K_SDATA:
	      do_sdata (idx, line, 0);
	      return 1;
	    case K_SDATAB:
	      do_sdatab (idx, line);
	      return 1;
	    case K_SDATAC:
	      do_sdata (idx, line, 'c');
	      return 1;
	    case K_SDATAZ:
	      do_sdata (idx, line, 'z');
	      return 1;
	    case K_ASSIGN:
	      do_assign (1, 0, line);
	      return 1;
	    case K_AIF:
	      do_aif (idx, line);
	      return 1;
	    case K_AREPEAT:
	      do_arepeat (idx, line);
	      return 1;
	    case K_AENDW:
	      do_aendw ();
	      return 1;
	    case K_AWHILE:
	      do_awhile (idx, line);
	      return 1;
	    case K_AENDR:
	      do_aendr ();
	      return 1;
	    case K_EQU:
	      do_assign (0, idx, line);
	      return 1;
	    case K_ALIGN:
	      do_align (idx, line);
	      return 1;
	    case K_RES:
	      do_res (idx, line, 0);
	      return 1;
	    case K_SRES:
	      do_res (idx, line, 's');
	      return 1;
	    case K_INCLUDE:
	      do_include (idx, line);
	      return 1;
	    case K_LOCAL:
	      do_local (idx, line);
	      return 1;
	    case K_MACRO:
	      do_macro (idx, line);
	      return 1;
	    case K_ENDM:
	      do_endm ();
	      return 1;
	    case K_SRESC:
	      do_res (idx, line, 'c');
	      return 1;
	    case K_PRINT:
	      do_print (idx, line);
	      return 1;
	    case K_FORM:
	      do_form (idx, line);
	      return 1;
	    case K_HEADING:
	      do_heading (idx, line);
	      return 1;
	    case K_PAGE:
	      do_page ();
	      return 1;
	    case K_GLOBAL:
	    case K_EXPORT:
	      do_export (line);
	      return 1;
	    case K_IMPORT:
	      return 1;
	    case K_SRESZ:
	      do_res (idx, line, 'z');
	      return 1;
	    case K_IGNORED:
	      return 1;
	    case K_END:
	      do_end (line);
	      return 1;
	    case K_ASSIGNA:
	      do_assigna (idx, line);
	      return 1;
	    case K_ASSIGNC:
	      do_assignc (idx, line);
	      return 1;
	    case K_EXITM:
	      do_exitm ();
	      return 1;
	    case K_REG:
	      do_reg (idx, line);
	      return 1;
	    case K_IFEQ:
	      do_if (idx, line, EQ);
	      return 1;
	    case K_IFNE:
	      do_if (idx, line, NE);
	      return 1;
	    case K_IFLT:
	      do_if (idx, line, LT);
	      return 1;
	    case K_IFLE:
	      do_if (idx, line, LE);
	      return 1;
	    case K_IFGE:
	      do_if (idx, line, GE);
	      return 1;
	    case K_IFGT:
	      do_if (idx, line, GT);
	      return 1;
	    case K_IFC:
	      do_ifc (idx, line, 0);
	      return 1;
	    case K_IFNC:
	      do_ifc (idx, line, 1);
	      return 1;
	    case K_IRP:
	      do_irp (idx, line, 0);
	      return 1;
	    case K_IRPC:
	      do_irp (idx, line, 1);
	      return 1;
	    }
	}
    }
  return 0;
}



/* Add a keyword to the hash table.  */

static void
add_keyword (name, code)
     const char *name;
     int code;
{
  sb label;
  int j;

  sb_new (&label);
  sb_add_string (&label, name);

  hash_add_to_int_table (&keyword_hash_table, &label, code);

  sb_reset (&label);
  for (j = 0; name[j]; j++)
    sb_add_char (&label, name[j] - 'A' + 'a');
  hash_add_to_int_table (&keyword_hash_table, &label, code);

  sb_kill (&label);
}  

/* Build the keyword hash table - put each keyword in the table twice,
   once upper and once lower case.*/

static void
process_init ()
{
  int i;

  for (i = 0; kinfo[i].name; i++)
    add_keyword (kinfo[i].name, kinfo[i].code);

  if (mri)
    {
      for (i = 0; mrikinfo[i].name; i++)
	add_keyword (mrikinfo[i].name, mrikinfo[i].code);
    }
}


static void
do_define (string)
     const char *string;
{
  sb label;
  int res = 1;
  hash_entry *ptr;
  sb_new (&label);


  while (*string)
    {
      if (*string == '=') 
	{
	  sb value;
	  sb_new (&value);
	  string++;
	  while (*string)
	    {
	      sb_add_char (&value, *string);
	      string++;
	    }
	  exp_get_abs ("Invalid expression on command line.\n", 0, &value, &res);
	  sb_kill (&value);
	  break;
	}
      sb_add_char (&label, *string);

      string ++;
    }

  ptr = hash_create (&vars, &label);
  free_old_entry (ptr);
  ptr->type = hash_integer;
  ptr->value.i = res;
  sb_kill (&label);
}
char *program_name;

/* The list of long options.  */
static struct option long_options[] =
{
  { "alternate", no_argument, 0, 'a' },
  { "include", required_argument, 0, 'I' },
  { "commentchar", required_argument, 0, 'c' },
  { "copysource", no_argument, 0, 's' },
  { "debug", no_argument, 0, 'd' },
  { "help", no_argument, 0, 'h' },
  { "mri", no_argument, 0, 'M' },
  { "output", required_argument, 0, 'o' },
  { "print", no_argument, 0, 'p' },
  { "unreasonable", no_argument, 0, 'u' },
  { "version", no_argument, 0, 'v' },
  { "define", required_argument, 0, 'd' },
  { NULL, no_argument, 0, 0 }
};

/* Show a usage message and exit.  */
static void
show_usage (file, status)
     FILE *file;
     int status;
{
  fprintf (file, "\
Usage: %s \n\
  [-a]      [--alternate]         enter alternate macro mode\n\
  [-c char] [--commentchar char]  change the comment character from !\n\
  [-d]      [--debug]             print some debugging info\n\
  [-h]      [--help]              print this message\n\
  [-M]      [--mri]               enter MRI compatibility mode\n\
  [-o out]  [--output out]        set the output file\n\
  [-p]      [--print]             print line numbers\n", program_name);
  fprintf (file, "\
  [-s]      [--copysource]        copy source through as comments \n\
  [-u]      [--unreasonable]      allow unreasonable nesting\n\
  [-v]      [--version]           print the program version\n\
  [-Dname=value]                  create preprocessor variable called name, with value\n\
  [-Ipath]                        add to include path list\n\
  [in-file]\n");
  exit (status);
}

/* Display a help message and exit.  */
static void
show_help ()
{
  printf ("%s: Gnu Assembler Macro Preprocessor\n",
	  program_name);
  show_usage (stdout, 0);
}

int
main (argc, argv)
     int argc;
     char **argv;
{
  int opt;
  char *out_name = 0;
  sp = include_stack;

  ifstack[0].on = 1;
  ifi = 0;



  program_name = argv[0];
  xmalloc_set_program_name (program_name);

  hash_new_table (101, &keyword_hash_table);
  hash_new_table (101, &assign_hash_table);
  hash_new_table (101, &vars);

  sb_new (&label);

  while ((opt = getopt_long (argc, argv, "I:sdhavc:upo:D:M", long_options,
			     (int *) NULL))
	 != EOF)
    {
      switch (opt)
	{
	case 'o':
	  out_name = optarg;
	  break;
	case 'u':
	  unreasonable = 1;
	  break;
	case 'I':
	  {
	    include_path *p = (include_path *) xmalloc (sizeof (include_path));
	    sb_new (&p->path);
	    sb_add_string (&p->path, optarg);
	    if (paths_tail)
	      paths_tail->next = p;
	    else
	      paths_head = p;
	    paths_tail = p;
	  }
	  break;
	case 'p':
	  print_line_number = 1;
	  break;
	case 'c':
	  comment_char = optarg[0];
	  break;
	case 'a':
	  alternate = 1;
	  break;
	case 's':
	  copysource = 1;
	  break;
	case 'd':
	  stats = 1;
	  break;
	case 'D':
	  do_define (optarg);
	  break;
	case 'M':
	  mri = 1;
	  comment_char = ';';
	  break;
	case 'h':
	  show_help ();
	  /*NOTREACHED*/
	case 'v':
	  printf ("GNU %s version %s\n", program_name, program_version);
	  exit (0);
	  /*NOTREACHED*/
	case 0:
	  break;
	default:
	  show_usage (stderr, 1);
	  /*NOTREACHED*/
	}
    }

  process_init ();

  macro_init (alternate, mri, 0, exp_get_abs);

  if (out_name) {
    outfile = fopen (out_name, "w");
    if (!outfile)
      {
	fprintf (stderr, "%s: Can't open output file `%s'.\n",
		 program_name, out_name);
	exit (1);
      }
  }
  else  {
    outfile = stdout;
  }

  chartype_init ();
  if (!outfile)
    outfile = stdout;

  /* Process all the input files */

  while (optind < argc)
    {
      if (new_file (argv[optind]))
	{
	  process_file ();
	}
      else
	{
	  fprintf (stderr, "%s: Can't open input file `%s'.\n",
		   program_name, argv[optind]);
	  exit (1);
	}
      optind++;
    }

  quit ();
  return 0;
}

/* This function is used because an abort in some of the other files
   may be compiled into as_abort because they include as.h.  */

void
as_abort (file, line, fn)
     const char *file, *fn;
     int line;
{
  fprintf (stderr, "Internal error, aborting at %s line %d", file, line);
  if (fn)
    fprintf (stderr, " in %s", fn);
  fprintf (stderr, "\nPlease report this bug.\n");
  exit (1);
}