• Andrew Hodgkinson's avatar
    Support for ANT URL broadcast message added. · 5a494095
    Andrew Hodgkinson authored
    Image deletion routines rewritten; nasty animated GIF bug now gone
    (it kept trying to update the cross-referenced image in the browser that
    no longer existed, and I've no idea how animated GIFs ever managed to *not*
    blow up if a cross referencing browser was shut down; and I've tested
    this...). There are now as many image structures as there are total images
    in the visible browsers, and no more; cross referenced images in the
    to-be-deleted browser have their ownership moved to the cross
    referencer before the cross referencee is wiped, with any required fetches
    being transferred with them.
    
    Reformatter sped up a bit by getting rid of strlen on the main text field
    of tokens in all places bar one, where it is called extremely rarely. This
    means direct app-to-app transfer of, say, a 359K text file to the browser
    won't run like a drain as it tries to do strlen on a 359K string over and
    over again! Most of the time the performance benefits won't really be
    noticable, but on the above text file, formatting time went down from
    290 seconds before the change to just under 7 seconds, a 41 fold speed
    increase or thereabouts (SA110 228MHz).
    
    MakeFile changed to force function name compilation on for debug builds
    (-fn in the DD...FLAGS); useful for certain functions such as
    register_null_handler, which can now output the name of the function
    being registered.
    
    ...Which helped show up some nasties in the animation handler and animation
    drift handler registration/deregistration process, which have been fixed
    (callers of fetchpage_release_nulls were unaware that the drift handler
    could be installed, and fragments of old code checking choices.anim_drift
    had a value other than 1 or 0 were still hanging around - bit tricky for
    a single bit item).
    
    Added support for VALIGN in table cells. Spotted a bug or two in the
    'what token is the pointer over' routines as a result, and fixed them - the
    worst was in browser_line_at_y, which checked the y coordinate was below
    the given one [the mouse], but didn't check the line height to see if the
    given y coordinate was *within* the line, rather than just above it. Never
    used to matter pre-tables, but a definite concern once multiple line
    arrays can exist on one page.
    5a494095
svcprint 8.86 KB
/* Copyright 1997 Acorn Computers Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifdef TRACE

  /* Undef USE_TML to use a debug file 'TMLDebug' in PipeFS rather */
  /* than the TML card output routines.                            */

  #define USE_TML

  #ifdef USE_TML

    /* -*-C-*-
     *
     * Copyright(c) 1994 Acorn Computers Ltd., Cambridge, England
     *
     * svcprint.c
     *
     * print debugging information down the TML tube link.
     *
     * provides:
     *         %s - string
     *         %C - character in range 20->7F (space printed if outside range)
     *         %c - any character
     *         %X - reverses order of bytes if >2 (or >4) specified as width
     *         %x - hex
     *         %B - reverses order of bytes if >2 (or >4) specified as width
     *         %b - binary
     *         %D - reverses order of bytes if >2 (or >4) specified as width
     *         %d - decimal
     *         %p - pointer ("@xxxxxxxx")
     *
     * field width can be specified by placing a decimal number after the "%"
     * character... if the width is started by a "0" then numbers are padded
     * with "0"...
     *
     * standard format specifiers o,u,e,f and g are NOT supported
     *
     */

    #include "kernel.h"
    #include "swis.h"
    #include "svcprint.h"

    #include "inetlib.h"

    #ifndef NULL
    # define NULL ((void *)0)
    #endif

    #ifdef DEBUG
    /*int debug = 1;*/
    #endif

    /**********************************************************************/

    /*
     * call processor mode independant character output routine
     */
    static void oswrch(unsigned char ch)
    {
        _kernel_swi_regs regset;

        /*
         * use HostFS_WriteC (SWI 0x40102) to print the character
         */
        regset.r[0] = ch;
        (void)_kernel_swi(0x40102, &regset, &regset);
    }

    /**********************************************************************/

    /*
     * Printn prints a number n in base b, minimum width w adding pad chars
     * if needed.
     */
    static void printn(unsigned n, unsigned b, int w, char pad)
    {
        if( n >= b )
        {
          printn(n / b, b, --w, pad);
          oswrch("0123456789abcdef"[n % b]);
        }
        else
        {
          while (--w > 0)
              oswrch(pad);

          oswrch("0123456789abcdef"[n]);
        }
    }

    /**********************************************************************/

    static void prf(char *format, unsigned *argp, ...)
    {
        register int b; /* base to be used when displaying numbers */
        register int c; /* current character read from format string */
        register int w; /* field width */
        char pad;     /* field padding character */
        unsigned val;   /* value of argument */

      loop:
        val = *argp;
        w = 0;
        pad = ' ';

        while( (c = *format++) != '%' )
        {
          if( c == '\0' )
              return;
          if( c == '\n' )
              oswrch('\r');
          oswrch(c);
        }

      again:
        /*
         * we have a special format command
         */
        c = *format++;
        switch( c )
        {
          case 's':
          {
              /* string */
              char *p = (char *)*argp++;
              int  width = 0;

              if (p != NULL)
              {
                  /* NOT a NULL pointer */
                  while (*p)
                  {
                      oswrch(*p++);
                      width++;
                  }
              }

              while( width++ < w )
                  oswrch(' ');
              goto loop;
          }

          case 'C':
          if( (*argp < ' ') || (*argp > '~') )
          {
              oswrch(' ');
              argp++;
              goto loop;
          }

          case 'c':
          /* character */
          oswrch(*argp++);
          goto loop;

          case '0':
          if (w == 0)
              pad = '0';

          case '1':
          case '2':
          case '3':
          case '4':
          case '5':
          case '6':
          case '7':
          case '8':
          case '9':
          /* field width */
          w = (w * 10) + ((int) c - '0');
          goto again;

          case 'X':
          /* hex number */
          if (w > 4)
              val = (unsigned)ntohl(val);
          else
          {
              if (w > 2)
                  val = (unsigned)ntohs(val);
          }

          /*
           * NB
           *
           * fall through to set base
           */

          case 'x':
          /* hex number */
          b = 16;
          goto number;

          case 'p':
                  /* pointer */
                  oswrch('@');
                  w = 8;
                  pad = '0';
                  b = 16;
                  goto number;

          case 'B':
          /* binary number */
          if (w > 4)
              val = (unsigned)ntohl(val);
          else
          {
              if( w > 2 )
                  val = (unsigned)ntohs(val);
          }

          /*
           * NB
           *
           * fall through to set base
           */

          case 'b':
          /* binary number */
          b = 2;
          goto number;

          case 'D':
          /* decimal number */
          if (w > 4)
              val = (unsigned)ntohl(val);
          else
          {
              if (w > 2)
                  val = (unsigned)ntohs(val);
          }

          /*
           * NB
           *
           * fall through to set base
           */

          case 'd':
          b = 10;
          /*
           * NB
           *
           * fall through to write number
           */

          number:
          printn(val,b,w,pad);
          argp++;

          break;
        } /* switch */

        goto loop;
    }


    /**********************************************************************/

    #if 0
    # define USETUBE
    #endif /* 0/1 */

    void Printf(char *format, ...)
    {
        unsigned *argp = (unsigned *)&format;
        static int inprf;

    #ifdef USETUBE
        _kernel_swi_regs reglist;
        _kernel_oserror *err;
    /*     int s = splhi(); */

        if( (err = _kernel_swi(0x40100, &reglist, &reglist)) != NULL )
        {
          prf("HostVDU: ", 0);
          prf(err->errmess, 0);
    /*    splx(s); */
          return;
        }
    #endif /* USETUBE */

        /*int s = splhi();*/
        if (inprf)
            return;

        inprf=1;
        prf(format, (argp + 1));
        inprf=0;
        /*splx(s);*/

    #ifdef USETUBE
        if( (err = _kernel_swi(0x40101, &reglist, &reglist)) != NULL )
        {
          prf("TubeVDU: ", 0);
          prf(err->errmess, 0);
    /*    splx(s); */
          return;
        }
    /*    splx(s); */
    #endif /* USETUBE */
    }

    /**********************************************************************/

    /* EOF svcprint.c */

  #else

    /* Make Printf use a PipeFS file instead of outputting to a TML card. */
    /* Because the routine calls fopen then fclose to avoid needing any   */
    /* initialisation or finalisation calls, do something like:           */
    /*                                                                    */
    /* REPEAT:OSCLI "Type Pipe:$.TMLDebug":UNTIL FALSE                    */
    /*                                                                    */
    /* in a Task Window to list the output during run-time (assuming this */
    /* was for a multitasking Wimp application). It isn't ideal, but it   */
    /* works out as better than nothing.                                  */
    /*                                                                    */
    /* History:                                                           */
    /*                                                                    */
    /* 11/08/97 (ADH): Created                                            */

    #include <stdlib.h>
    #include <stdarg.h>
    #include <stdio.h>

    void Printf(char * format, ...)
    {
      va_list   ptr;
      FILE    * fp;

      #define Debug_FileName "Devices:Parallel"

      fp = fopen(Debug_FileName, "wab");
      if (!fp) fp = fopen(Debug_FileName, "wb");
      if (!fp) return;

      setvbuf(fp, NULL, _IONBF, 0);

      va_start(ptr, format);
      vfprintf(fp, format, ptr);
      va_end(ptr);

      fclose(fp);
    }

  #endif

#else

  static void svcprint_keep_compiler_happy(void)
  {
    int a;
    a = 0;
  }

#endif